Commit a16337a47889d4af376111983a2dcce7520d42f0

Authored by xp.Huang
2 parents 426b4948 f5997cea

Merge branch 'ww' into 'main'

Ww

See merge request huang/thingskit-drawio!7

Too many changes to show.

To preserve performance only 5 of 8 files are displayed.

  1 +<component name="ProjectDictionaryState">
  2 + <dictionary name="WWN">
  3 + <words>
  4 + <w>layui</w>
  5 + </words>
  6 + </dictionary>
  7 +</component>
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<project version="4">
  3 + <component name="VcsDirectoryMappings">
  4 + <mapping directory="$PROJECT_DIR$" vcs="Git" />
  5 + </component>
  6 +</project>
@@ -9,7 +9,7 @@ @@ -9,7 +9,7 @@
9 <meta name="Keywords" content="diagram, online, flow chart, flowchart maker, uml, erd"> 9 <meta name="Keywords" content="diagram, online, flow chart, flowchart maker, uml, erd">
10 <meta itemprop="name" content="diagrams.net - free flowchart maker and diagrams online"> 10 <meta itemprop="name" content="diagrams.net - free flowchart maker and diagrams online">
11 <meta itemprop="description" content="diagrams.net is a free online diagramming application and flowchart maker . You can use it to create UML, entity relationship, 11 <meta itemprop="description" content="diagrams.net is a free online diagramming application and flowchart maker . You can use it to create UML, entity relationship,
12 - org charts, BPMN and BPM, database schema and networks. Also possible are telecommunication network, workflow, flowcharts, maps overlays and GIS, electronic 12 + org charts, BPMN and BPM, database schema and networks. Also possible are telecommunication network, workflow, flowcharts, maps overlays and GIS, electronic
13 circuit and social network diagrams."> 13 circuit and social network diagrams.">
14 <meta itemprop="image" content="https://lh4.googleusercontent.com/-cLKEldMbT_E/Tx8qXDuw6eI/AAAAAAAAAAs/Ke0pnlk8Gpg/w500-h344-k/BPMN%2Bdiagram%2Brc2f.png"> 14 <meta itemprop="image" content="https://lh4.googleusercontent.com/-cLKEldMbT_E/Tx8qXDuw6eI/AAAAAAAAAAs/Ke0pnlk8Gpg/w500-h344-k/BPMN%2Bdiagram%2Brc2f.png">
15 <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"> 15 <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
@@ -17,18 +17,25 @@ @@ -17,18 +17,25 @@
17 <meta name="mobile-web-app-capable" content="yes"> 17 <meta name="mobile-web-app-capable" content="yes">
18 <meta name="theme-color" content="#d89000"> 18 <meta name="theme-color" content="#d89000">
19 <script src="./plugins/axios.min.js"></script> 19 <script src="./plugins/axios.min.js"></script>
20 - <script src="./js/jquery/jquery-3.3.1.min.js"></script>  
21 - <script src="./js/jquery.easyui.min.js"></script> 20 +<!-- <script src="./js/jquery/jquery-3.3.1.min.js"></script>-->
  21 +<!-- <script src="./js/jquery.easyui.min.js"></script>-->
22 <link rel="stylesheet" href="https://cdnjs.loli.net/ajax/libs/layui/2.6.8/css/layui.min.css" integrity="sha512-iQBJbsNHXUcgEIgWThd2dr8tOdKPvICwqjPEZYY81z3eMya44A5MiAqfWSCh+Ee1YzNYkdrI982Qhwgr8LEYOQ==" crossorigin="anonymous" referrerpolicy="no-referrer" /> 22 <link rel="stylesheet" href="https://cdnjs.loli.net/ajax/libs/layui/2.6.8/css/layui.min.css" integrity="sha512-iQBJbsNHXUcgEIgWThd2dr8tOdKPvICwqjPEZYY81z3eMya44A5MiAqfWSCh+Ee1YzNYkdrI982Qhwgr8LEYOQ==" crossorigin="anonymous" referrerpolicy="no-referrer" />
23 <script src="https://cdnjs.loli.net/ajax/libs/layui/2.6.8/layui.min.js" integrity="sha512-EKrFvch3qTzLFQgjbcjpsRmF8T3UCtc9ojtMAu6dvvP+bV8qYUDOaQ84nwYCkSLT7lbqGoya/Kf+8fyCBE0vRg==" crossorigin="anonymous" referrerpolicy="no-referrer"></script> 23 <script src="https://cdnjs.loli.net/ajax/libs/layui/2.6.8/layui.min.js" integrity="sha512-EKrFvch3qTzLFQgjbcjpsRmF8T3UCtc9ojtMAu6dvvP+bV8qYUDOaQ84nwYCkSLT7lbqGoya/Kf+8fyCBE0vRg==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
24 - 24 +
  25 + <!-- 引入修改样式 -->
  26 + <link rel="stylesheet" href="./styles/formatChange.css">
  27 +
25 <!-- 引入select.zTree及相关依赖 --> 28 <!-- 引入select.zTree及相关依赖 -->
26 - <link rel="stylesheet" href="./styles/zTreeStyle.css" type="text/css">  
27 - <link rel="stylesheet" href="./styles/jquery.select.zTree.v1.5.css" type="text/css">  
28 - <script type="text/javascript" src="./js/jquery.ztree.core.min.js"></script>  
29 - <script type="text/javascript" src="./js/jquery.ztree.exhide.min.js"></script>  
30 - <script type="text/javascript" src="./js/jquery.select.zTree.v1.5.min.js"></script> 29 +<!-- <link rel="stylesheet" href="./styles/zTreeStyle.css" type="text/css">-->
  30 +<!-- <link rel="stylesheet" href="./styles/jquery.select.zTree.v1.5.css" type="text/css">-->
  31 +<!-- <script type="text/javascript" src="./js/jquery.ztree.core.min.js"></script>-->
  32 +<!-- <script type="text/javascript" src="./js/jquery.ztree.exhide.min.js"></script>-->
  33 +<!-- <script type="text/javascript" src="./js/jquery.select.zTree.v1.5.min.js"></script>-->
  34 +
  35 +<!-- Axios -->
31 <script src="./plugins/defHttp.js"></script> 36 <script src="./plugins/defHttp.js"></script>
  37 +
  38 + <script src="./js/api/index.js"></script>
32 39
33 <script type="text/javascript"> 40 <script type="text/javascript">
34 /** 41 /**
@@ -54,27 +61,27 @@ @@ -54,27 +61,27 @@
54 { 61 {
55 var result = new Object(); 62 var result = new Object();
56 var params = window.location.search.slice(1).split('&'); 63 var params = window.location.search.slice(1).split('&');
57 - 64 +
58 for (var i = 0; i < params.length; i++) 65 for (var i = 0; i < params.length; i++)
59 { 66 {
60 var idx = params[i].indexOf('='); 67 var idx = params[i].indexOf('=');
61 - 68 +
62 if (idx > 0) 69 if (idx > 0)
63 { 70 {
64 result[params[i].substring(0, idx)] = params[i].substring(idx + 1); 71 result[params[i].substring(0, idx)] = params[i].substring(idx + 1);
65 } 72 }
66 } 73 }
67 - 74 +
68 return result; 75 return result;
69 })(); 76 })();
70 - 77 +
71 // Forces CDN caches by passing URL parameters via URL hash 78 // Forces CDN caches by passing URL parameters via URL hash
72 if (window.location.hash != null && window.location.hash.substring(0, 2) == '#P') 79 if (window.location.hash != null && window.location.hash.substring(0, 2) == '#P')
73 { 80 {
74 try 81 try
75 { 82 {
76 urlParams = JSON.parse(decodeURIComponent(window.location.hash.substring(2))); 83 urlParams = JSON.parse(decodeURIComponent(window.location.hash.substring(2)));
77 - 84 +
78 if (urlParams.hash != null) 85 if (urlParams.hash != null)
79 { 86 {
80 window.location.hash = urlParams.hash; 87 window.location.hash = urlParams.hash;
@@ -85,7 +92,7 @@ @@ -85,7 +92,7 @@
85 // ignore 92 // ignore
86 } 93 }
87 } 94 }
88 - 95 +
89 // Global variable for desktop 96 // Global variable for desktop
90 var mxIsElectron = window && window.process && window.process.type; 97 var mxIsElectron = window && window.process && window.process.type;
91 98
@@ -95,21 +102,21 @@ @@ -95,21 +102,21 @@
95 (function() 102 (function()
96 { 103 {
97 var proto = window.location.protocol; 104 var proto = window.location.protocol;
98 - 105 +
99 if (!mxIsElectron) 106 if (!mxIsElectron)
100 { 107 {
101 var host = window.location.host; 108 var host = window.location.host;
102 - 109 +
103 // Redirects apex, drive and rt to www 110 // Redirects apex, drive and rt to www
104 if (host === 'draw.io' || host === 'rt.draw.io' || host === 'drive.draw.io') 111 if (host === 'draw.io' || host === 'rt.draw.io' || host === 'drive.draw.io')
105 { 112 {
106 host = 'www.draw.io'; 113 host = 'www.draw.io';
107 } 114 }
108 - 115 +
109 var href = proto + '//' + host + window.location.href.substring( 116 var href = proto + '//' + host + window.location.href.substring(
110 window.location.protocol.length + 117 window.location.protocol.length +
111 window.location.host.length + 2); 118 window.location.host.length + 2);
112 - 119 +
113 // Redirects if href changes 120 // Redirects if href changes
114 if (href != window.location.href) 121 if (href != window.location.href)
115 { 122 {
@@ -118,7 +125,7 @@ @@ -118,7 +125,7 @@
118 } 125 }
119 })(); 126 })();
120 } 127 }
121 - 128 +
122 /** 129 /**
123 * Adds meta tag to the page. 130 * Adds meta tag to the page.
124 */ 131 */
@@ -127,15 +134,15 @@ @@ -127,15 +134,15 @@
127 try 134 try
128 { 135 {
129 var s = document.createElement('meta'); 136 var s = document.createElement('meta');
130 -  
131 - if (name != null) 137 +
  138 + if (name != null)
132 { 139 {
133 s.setAttribute('name', name); 140 s.setAttribute('name', name);
134 } 141 }
135 142
136 s.setAttribute('content', content); 143 s.setAttribute('content', content);
137 -  
138 - if (httpEquiv != null) 144 +
  145 + if (httpEquiv != null)
139 { 146 {
140 s.setAttribute('http-equiv', httpEquiv); 147 s.setAttribute('http-equiv', httpEquiv);
141 } 148 }
@@ -148,14 +155,14 @@ @@ -148,14 +155,14 @@
148 // ignore 155 // ignore
149 } 156 }
150 }; 157 };
151 - 158 +
152 /** 159 /**
153 * Synchronously adds scripts to the page. 160 * Synchronously adds scripts to the page.
154 */ 161 */
155 function mxscript(src, onLoad, id, dataAppKey, noWrite) 162 function mxscript(src, onLoad, id, dataAppKey, noWrite)
156 { 163 {
157 var defer = onLoad == null && !noWrite; 164 var defer = onLoad == null && !noWrite;
158 - 165 +
159 if ((urlParams['dev'] != '1' && typeof document.createElement('canvas').getContext === "function") || 166 if ((urlParams['dev'] != '1' && typeof document.createElement('canvas').getContext === "function") ||
160 onLoad != null || noWrite) 167 onLoad != null || noWrite)
161 { 168 {
@@ -168,16 +175,16 @@ @@ -168,16 +175,16 @@
168 { 175 {
169 s.setAttribute('id', id); 176 s.setAttribute('id', id);
170 } 177 }
171 - 178 +
172 if (dataAppKey != null) 179 if (dataAppKey != null)
173 { 180 {
174 s.setAttribute('data-app-key', dataAppKey); 181 s.setAttribute('data-app-key', dataAppKey);
175 } 182 }
176 - 183 +
177 if (onLoad != null) 184 if (onLoad != null)
178 { 185 {
179 var r = false; 186 var r = false;
180 - 187 +
181 s.onload = s.onreadystatechange = function() 188 s.onload = s.onreadystatechange = function()
182 { 189 {
183 if (!r && (!this.readyState || this.readyState == 'complete')) 190 if (!r && (!this.readyState || this.readyState == 'complete'))
@@ -187,9 +194,9 @@ @@ -187,9 +194,9 @@
187 } 194 }
188 }; 195 };
189 } 196 }
190 - 197 +
191 var t = document.getElementsByTagName('script')[0]; 198 var t = document.getElementsByTagName('script')[0];
192 - 199 +
193 if (t != null) 200 if (t != null)
194 { 201 {
195 t.parentNode.insertBefore(s, t); 202 t.parentNode.insertBefore(s, t);
@@ -211,11 +218,11 @@ @@ -211,11 +218,11 @@
211 g.type = 'text/javascript'; 218 g.type = 'text/javascript';
212 g.async = true; 219 g.async = true;
213 g.src = src; 220 g.src = src;
214 - 221 +
215 var s = document.getElementsByTagName('script')[0]; 222 var s = document.getElementsByTagName('script')[0];
216 s.parentNode.insertBefore(g, s); 223 s.parentNode.insertBefore(g, s);
217 }; 224 };
218 - 225 +
219 /** 226 /**
220 * Adds meta tags with application name (depends on offline URL parameter) 227 * Adds meta tags with application name (depends on offline URL parameter)
221 */ 228 */
@@ -230,10 +237,10 @@ @@ -230,10 +237,10 @@
230 mxmeta(null, 'default-src \'self\' \'unsafe-inline\'; connect-src \'self\' https://*.draw.io https://fonts.googleapis.com https://fonts.gstatic.com; img-src * data:; media-src *; font-src *; style-src-elem \'self\' \'unsafe-inline\' https://fonts.googleapis.com', 'Content-Security-Policy'); 237 mxmeta(null, 'default-src \'self\' \'unsafe-inline\'; connect-src \'self\' https://*.draw.io https://fonts.googleapis.com https://fonts.gstatic.com; img-src * data:; media-src *; font-src *; style-src-elem \'self\' \'unsafe-inline\' https://fonts.googleapis.com', 'Content-Security-Policy');
231 } 238 }
232 })(); 239 })();
233 - 240 +
234 // Checks for local storage 241 // Checks for local storage
235 var isLocalStorage = false; 242 var isLocalStorage = false;
236 - 243 +
237 try 244 try
238 { 245 {
239 isLocalStorage = urlParams['local'] != '1' && typeof(localStorage) != 'undefined'; 246 isLocalStorage = urlParams['local'] != '1' && typeof(localStorage) != 'undefined';
@@ -244,15 +251,15 @@ @@ -244,15 +251,15 @@
244 } 251 }
245 252
246 var mxScriptsLoaded = false, mxWinLoaded = false; 253 var mxScriptsLoaded = false, mxWinLoaded = false;
247 - 254 +
248 function checkAllLoaded() 255 function checkAllLoaded()
249 { 256 {
250 if (mxScriptsLoaded && mxWinLoaded) 257 if (mxScriptsLoaded && mxWinLoaded)
251 { 258 {
252 - App.main(); 259 + App.main();
253 } 260 }
254 }; 261 };
255 - 262 +
256 var t0 = new Date(); 263 var t0 = new Date();
257 264
258 // Changes paths for local development environment 265 // Changes paths for local development environment
@@ -260,18 +267,18 @@ @@ -260,18 +267,18 @@
260 { 267 {
261 // Used to request grapheditor/mxgraph sources in dev mode 268 // Used to request grapheditor/mxgraph sources in dev mode
262 var mxDevUrl = document.location.protocol + '//devhost.jgraph.com/drawio/src/main'; 269 var mxDevUrl = document.location.protocol + '//devhost.jgraph.com/drawio/src/main';
263 - 270 +
264 // Used to request draw.io sources in dev mode 271 // Used to request draw.io sources in dev mode
265 var drawDevUrl = document.location.protocol + '//devhost.jgraph.com/drawio/src/main/webapp/'; 272 var drawDevUrl = document.location.protocol + '//devhost.jgraph.com/drawio/src/main/webapp/';
266 var geBasePath = drawDevUrl + '/js/grapheditor'; 273 var geBasePath = drawDevUrl + '/js/grapheditor';
267 var mxBasePath = mxDevUrl + '/mxgraph'; 274 var mxBasePath = mxDevUrl + '/mxgraph';
268 - 275 +
269 if (document.location.protocol == 'file:') 276 if (document.location.protocol == 'file:')
270 { 277 {
271 geBasePath = './js/grapheditor'; 278 geBasePath = './js/grapheditor';
272 mxBasePath = './mxgraph'; 279 mxBasePath = './mxgraph';
273 drawDevUrl = './'; 280 drawDevUrl = './';
274 - 281 +
275 // Forces includes for dev environment in node.js 282 // Forces includes for dev environment in node.js
276 mxForceIncludes = true; 283 mxForceIncludes = true;
277 } 284 }
@@ -287,19 +294,19 @@ @@ -287,19 +294,19 @@
287 mxscript(drawDevUrl + 'js/diagramly/Init.js'); 294 mxscript(drawDevUrl + 'js/diagramly/Init.js');
288 mxscript(geBasePath + '/Init.js'); 295 mxscript(geBasePath + '/Init.js');
289 mxscript(mxBasePath + '/mxClient.js'); 296 mxscript(mxBasePath + '/mxClient.js');
290 - 297 +
291 // Adds all JS code that depends on mxClient. This indirection via Devel.js is 298 // Adds all JS code that depends on mxClient. This indirection via Devel.js is
292 // required in some browsers to make sure mxClient.js (and the files that it 299 // required in some browsers to make sure mxClient.js (and the files that it
293 // loads asynchronously) are available when the code loaded in Devel.js runs. 300 // loads asynchronously) are available when the code loaded in Devel.js runs.
294 mxscript(drawDevUrl + 'js/diagramly/Devel.js'); 301 mxscript(drawDevUrl + 'js/diagramly/Devel.js');
295 - 302 +
296 // Electron 303 // Electron
297 if (mxIsElectron) 304 if (mxIsElectron)
298 { 305 {
299 mxscript('js/diagramly/DesktopLibrary.js'); 306 mxscript('js/diagramly/DesktopLibrary.js');
300 mxscript('js/diagramly/ElectronApp.js'); 307 mxscript('js/diagramly/ElectronApp.js');
301 } 308 }
302 - 309 +
303 mxscript(drawDevUrl + 'js/PostConfig.js'); 310 mxscript(drawDevUrl + 'js/PostConfig.js');
304 } 311 }
305 else 312 else
@@ -307,18 +314,18 @@ @@ -307,18 +314,18 @@
307 (function() 314 (function()
308 { 315 {
309 var hostName = window.location.hostname; 316 var hostName = window.location.hostname;
310 - 317 +
311 // Supported domains are *.draw.io and the packaged version in Quip 318 // Supported domains are *.draw.io and the packaged version in Quip
312 var supportedDomain = (hostName.substring(hostName.length - 8, hostName.length) === '.draw.io') || 319 var supportedDomain = (hostName.substring(hostName.length - 8, hostName.length) === '.draw.io') ||
313 (hostName.substring(hostName.length - 13, hostName.length) === '.diagrams.net'); 320 (hostName.substring(hostName.length - 13, hostName.length) === '.diagrams.net');
314 - 321 +
315 function loadAppJS() 322 function loadAppJS()
316 { 323 {
317 mxscript('js/app.min.js', function() 324 mxscript('js/app.min.js', function()
318 { 325 {
319 mxScriptsLoaded = true; 326 mxScriptsLoaded = true;
320 checkAllLoaded(); 327 checkAllLoaded();
321 - 328 +
322 // Electron 329 // Electron
323 if (mxIsElectron) 330 if (mxIsElectron)
324 { 331 {
@@ -345,7 +352,7 @@ @@ -345,7 +352,7 @@
345 } 352 }
346 }); 353 });
347 }; 354 };
348 - 355 +
349 if (!supportedDomain || mxIsElectron) 356 if (!supportedDomain || mxIsElectron)
350 { 357 {
351 mxscript('js/PreConfig.js', loadAppJS); 358 mxscript('js/PreConfig.js', loadAppJS);
@@ -361,7 +368,7 @@ @@ -361,7 +368,7 @@
361 window.onerror = function() 368 window.onerror = function()
362 { 369 {
363 var status = document.getElementById('geStatus'); 370 var status = document.getElementById('geStatus');
364 - 371 +
365 if (status != null) 372 if (status != null)
366 { 373 {
367 status.innerHTML = 'Page could not be loaded. Please try refreshing.'; 374 status.innerHTML = 'Page could not be loaded. Please try refreshing.';
@@ -461,7 +468,7 @@ if (navigator.userAgent != null && navigator.userAgent.toLowerCase(). @@ -461,7 +468,7 @@ if (navigator.userAgent != null && navigator.userAgent.toLowerCase().
461 { 468 {
462 // Redirects old Electron app to latest version 469 // Redirects old Electron app to latest version
463 var div = document.getElementById('geInfo'); 470 var div = document.getElementById('geInfo');
464 - 471 +
465 if (div != null) 472 if (div != null)
466 { 473 {
467 div.innerHTML = '<center><h2>You are using an out of date version of this app.<br>Please download the latest version ' + 474 div.innerHTML = '<center><h2>You are using an out of date version of this app.<br>Please download the latest version ' +
  1 +class ConfigurationNodeApi {
  2 + /**
  3 + * @description 获取组态信息
  4 + * @param {'CONFIGURE' | 'CONTENT' | 'NODE'} levelType - 组态资源类型
  5 + * @param {string} levelId - 组态资源ID
  6 + */
  7 + static getConfigurationInfo(levelType, levelId) {
  8 + return defHttp.get(`/yt/configuration/node/${levelType}/${levelId}`)
  9 + }
  10 +
  11 + /**
  12 + * @description 获取组织节点树
  13 + * @returns
  14 + */
  15 + static getOrgTree() {
  16 + return defHttp.get('/yt/organization/me/list')
  17 + }
  18 +
  19 + /**
  20 + * @description 通过设备ID 获取 设备属性
  21 + * @param tbDeviceId
  22 + * @returns {Promise<*>}
  23 + */
  24 + static getDeviceAttr(tbDeviceId) {
  25 + return defHttp.get(`/plugins/telemetry/DEVICE/${tbDeviceId}/keys/timeseries`)
  26 + }
  27 +
  28 + /**
  29 + * @description 获取组织下的设备
  30 + * @param {'DIRECT_CONNECTION' | 'GATEWAY' | 'SENDOR'} deviceType - 'DIRECT_CONNECTION' 直连设备 'GATEWAY' 网关设备 'SENDOR' 传感器
  31 + * @param {string} orgId - 组织ID
  32 + * @returns {Promise<*>}
  33 + */
  34 + static getDeviceUnderTheOrg(deviceType, orgId) {
  35 + return defHttp.get(`/yt/device/list/${deviceType}?organizationId=${orgId}`)
  36 + }
  37 +
  38 + /**
  39 + * @description 查询设备的子设备
  40 + * @param deviceId 设备ID
  41 + * @returns {Promise<*>}
  42 + */
  43 + static getDeviceChildDevice(deviceId) {
  44 + return defHttp.get(`/yt/device/relation?page=1&pageSize=10&fromId=${deviceId}`)
  45 + }
  46 +
  47 + /**
  48 + * @description 查询所有主设备列表
  49 + * @param orgId
  50 + * @returns {Promise<*>}
  51 + */
  52 + static getMasterDevice(orgId) {
  53 + return defHttp.get(`/yt/device/list/master/${orgId}`)
  54 + }
  55 +
  56 + /**
  57 + * @description 查询所有从设备
  58 + * @param orgId
  59 + * @param masterDeviceId
  60 + * @returns {Promise<*>}
  61 + */
  62 + static getSlaveDevice(orgId, masterDeviceId) {
  63 + return defHttp.get(`/yt/device/list/slave/${orgId}?masterId=${masterDeviceId}`)
  64 + }
  65 +
  66 + /**
  67 + * @description 编辑数据交互
  68 + */
  69 + static updateNodeEvent(data) {
  70 + return defHttp.post('/yt/configuration/node/event', data)
  71 + }
  72 +
  73 + /**
  74 + * @description 编辑动画效果
  75 + * @param {*} data
  76 + * @returns
  77 + */
  78 + static updateNodeAct(data) {
  79 + return defHttp.post('/yt/configuration/node/act', data)
  80 + }
  81 +}
@@ -16,14 +16,14 @@ App = function(editor, container, lightbox) @@ -16,14 +16,14 @@ App = function(editor, container, lightbox)
16 EditorUi.call(this, editor, container, (lightbox != null) ? lightbox : 16 EditorUi.call(this, editor, container, (lightbox != null) ? lightbox :
17 (urlParams['lightbox'] == '1' || (uiTheme == 'min' && 17 (urlParams['lightbox'] == '1' || (uiTheme == 'min' &&
18 urlParams['chrome'] != '0'))); 18 urlParams['chrome'] != '0')));
19 - 19 +
20 // Logs unloading of window with modifications for Google Drive file 20 // Logs unloading of window with modifications for Google Drive file
21 if (!mxClient.IS_CHROMEAPP && !EditorUi.isElectronApp) 21 if (!mxClient.IS_CHROMEAPP && !EditorUi.isElectronApp)
22 { 22 {
23 window.onunload = mxUtils.bind(this, function() 23 window.onunload = mxUtils.bind(this, function()
24 { 24 {
25 var file = this.getCurrentFile(); 25 var file = this.getCurrentFile();
26 - 26 +
27 if (file != null && file.isModified()) 27 if (file != null && file.isModified())
28 { 28 {
29 var evt = {category: 'DISCARD-FILE-' + file.getHash(), 29 var evt = {category: 'DISCARD-FILE-' + file.getHash(),
@@ -39,7 +39,7 @@ App = function(editor, container, lightbox) @@ -39,7 +39,7 @@ App = function(editor, container, lightbox)
39 '-change_' + ((file.lastChanged != null) ? Math.round((Date.now() - file.lastChanged.getTime()) / 1000) : 'x') + 39 '-change_' + ((file.lastChanged != null) ? Math.round((Date.now() - file.lastChanged.getTime()) / 1000) : 'x') +
40 '-alive_' + Math.round((Date.now() - App.startTime.getTime()) / 1000), 40 '-alive_' + Math.round((Date.now() - App.startTime.getTime()) / 1000),
41 label: (file.sync != null) ? ('client_' + file.sync.clientId) : 'nosync'}; 41 label: (file.sync != null) ? ('client_' + file.sync.clientId) : 'nosync'};
42 - 42 +
43 if (file.constructor == DriveFile && file.desc != null && this.drive != null) 43 if (file.constructor == DriveFile && file.desc != null && this.drive != null)
44 { 44 {
45 evt.label += ((this.drive.user != null) ? ('-user_' + this.drive.user.id) : '-nouser') + '-rev_' + 45 evt.label += ((this.drive.user != null) ? ('-user_' + this.drive.user.id) : '-nouser') + '-rev_' +
@@ -56,7 +56,7 @@ App = function(editor, container, lightbox) @@ -56,7 +56,7 @@ App = function(editor, container, lightbox)
56 this.editor.addListener('autosaveChanged', mxUtils.bind(this, function() 56 this.editor.addListener('autosaveChanged', mxUtils.bind(this, function()
57 { 57 {
58 var file = this.getCurrentFile(); 58 var file = this.getCurrentFile();
59 - 59 +
60 if (file != null) 60 if (file != null)
61 { 61 {
62 EditorUi.logEvent({category: ((this.editor.autosave) ? 'ON' : 'OFF') + 62 EditorUi.logEvent({category: ((this.editor.autosave) ? 'ON' : 'OFF') +
@@ -64,7 +64,7 @@ App = function(editor, container, lightbox) @@ -64,7 +64,7 @@ App = function(editor, container, lightbox)
64 label: 'autosave_' + ((this.editor.autosave) ? 'on' : 'off')}); 64 label: 'autosave_' + ((this.editor.autosave) ? 'on' : 'off')});
65 } 65 }
66 })); 66 }));
67 - 67 +
68 // Pre-fetches images 68 // Pre-fetches images
69 if (mxClient.IS_SVG) 69 if (mxClient.IS_SVG)
70 { 70 {
@@ -75,7 +75,7 @@ App = function(editor, container, lightbox) @@ -75,7 +75,7 @@ App = function(editor, container, lightbox)
75 var img = new Image(); 75 var img = new Image();
76 img.src = mxGraph.prototype.warningImage.src; 76 img.src = mxGraph.prototype.warningImage.src;
77 } 77 }
78 - 78 +
79 // Global helper method to deal with popup blockers 79 // Global helper method to deal with popup blockers
80 window.openWindow = mxUtils.bind(this, function(url, pre, fallback) 80 window.openWindow = mxUtils.bind(this, function(url, pre, fallback)
81 { 81 {
@@ -84,9 +84,9 @@ App = function(editor, container, lightbox) @@ -84,9 +84,9 @@ App = function(editor, container, lightbox)
84 fallback(); 84 fallback();
85 return; 85 return;
86 } 86 }
87 - 87 +
88 var wnd = null; 88 var wnd = null;
89 - 89 +
90 try 90 try
91 { 91 {
92 wnd = window.open(url); 92 wnd = window.open(url);
@@ -95,7 +95,7 @@ App = function(editor, container, lightbox) @@ -95,7 +95,7 @@ App = function(editor, container, lightbox)
95 { 95 {
96 // ignore 96 // ignore
97 } 97 }
98 - 98 +
99 if (wnd == null || wnd === undefined) 99 if (wnd == null || wnd === undefined)
100 { 100 {
101 this.showDialog(new PopupDialog(this, url, pre, fallback).container, 320, 140, true, true); 101 this.showDialog(new PopupDialog(this, url, pre, fallback).container, 320, 140, true, true);
@@ -118,7 +118,7 @@ App = function(editor, container, lightbox) @@ -118,7 +118,7 @@ App = function(editor, container, lightbox)
118 { 118 {
119 window.openFile.cancel(true); 119 window.openFile.cancel(true);
120 } 120 }
121 - 121 +
122 this.handleError(message); 122 this.handleError(message);
123 }); 123 });
124 124
@@ -127,7 +127,7 @@ App = function(editor, container, lightbox) @@ -127,7 +127,7 @@ App = function(editor, container, lightbox)
127 { 127 {
128 this.addFileDropHandler([document]); 128 this.addFileDropHandler([document]);
129 } 129 }
130 - 130 +
131 // Process the queue for waiting plugins 131 // Process the queue for waiting plugins
132 if (App.DrawPlugins != null) 132 if (App.DrawPlugins != null)
133 { 133 {
@@ -150,7 +150,7 @@ App = function(editor, container, lightbox) @@ -150,7 +150,7 @@ App = function(editor, container, lightbox)
150 this.initializeEmbedMode(); 150 this.initializeEmbedMode();
151 } 151 }
152 } 152 }
153 - 153 +
154 // Installs global callback for plugins 154 // Installs global callback for plugins
155 window.Draw.loadPlugin = mxUtils.bind(this, function(callback) 155 window.Draw.loadPlugin = mxUtils.bind(this, function(callback)
156 { 156 {
@@ -164,7 +164,7 @@ App = function(editor, container, lightbox) @@ -164,7 +164,7 @@ App = function(editor, container, lightbox)
164 this.initializeEmbedMode(); 164 this.initializeEmbedMode();
165 } 165 }
166 }); 166 });
167 - 167 +
168 //Set a timeout in case a plugin doesn't load quickly or doesn't load at all 168 //Set a timeout in case a plugin doesn't load quickly or doesn't load at all
169 setTimeout(mxUtils.bind(this, function() 169 setTimeout(mxUtils.bind(this, function()
170 { 170 {
@@ -292,7 +292,7 @@ App.PUSHER_CLUSTER = 'eu'; @@ -292,7 +292,7 @@ App.PUSHER_CLUSTER = 'eu';
292 App.PUSHER_URL = 'https://js.pusher.com/7.0.3/pusher.min.js'; 292 App.PUSHER_URL = 'https://js.pusher.com/7.0.3/pusher.min.js';
293 293
294 /** 294 /**
295 - * SimplePeer library 295 + * SimplePeer library
296 */ 296 */
297 App.SIMPLE_PEER_URL = window.DRAWIO_BASE_URL + '/js/simplepeer/simplepeer9.10.0.min.js'; 297 App.SIMPLE_PEER_URL = window.DRAWIO_BASE_URL + '/js/simplepeer/simplepeer9.10.0.min.js';
298 298
@@ -300,11 +300,11 @@ App.PUSHER_URL = 'https://js.pusher.com/7.0.3/pusher.min.js'; @@ -300,11 +300,11 @@ App.PUSHER_URL = 'https://js.pusher.com/7.0.3/pusher.min.js';
300 * Google APIs to load. The realtime API is needed to notify collaborators of conversion 300 * Google APIs to load. The realtime API is needed to notify collaborators of conversion
301 * of the realtime files, but after Dec 11 it's read-only and hence no longer needed. 301 * of the realtime files, but after Dec 11 it's read-only and hence no longer needed.
302 */ 302 */
303 -App.GOOGLE_APIS = 'drive-share'; 303 +App.GOOGLE_APIS = 'drive-share';
304 304
305 /** 305 /**
306 * Function: authorize 306 * Function: authorize
307 - * 307 + *
308 * Authorizes the client, gets the userId and calls <open>. 308 * Authorizes the client, gets the userId and calls <open>.
309 */ 309 */
310 App.startTime = new Date(); 310 App.startTime = new Date();
@@ -316,7 +316,7 @@ App.startTime = new Date(); @@ -316,7 +316,7 @@ App.startTime = new Date();
316 App.pluginRegistry = {'4xAKTrabTpTzahoLthkwPNUn': 'plugins/explore.js', 316 App.pluginRegistry = {'4xAKTrabTpTzahoLthkwPNUn': 'plugins/explore.js',
317 'ex': 'plugins/explore.js', 'p1': 'plugins/p1.js', 317 'ex': 'plugins/explore.js', 'p1': 'plugins/p1.js',
318 'ac': 'plugins/connect.js', 'acj': 'plugins/connectJira.js', 318 'ac': 'plugins/connect.js', 'acj': 'plugins/connectJira.js',
319 - 'ac148': 'plugins/cConf-1-4-8.js', 'ac148cmnt': 'plugins/cConf-comments.js', 319 + 'ac148': 'plugins/cConf-1-4-8.js', 'ac148cmnt': 'plugins/cConf-comments.js',
320 'voice': 'plugins/voice.js', 320 'voice': 'plugins/voice.js',
321 'tips': 'plugins/tooltips.js', 'svgdata': 'plugins/svgdata.js', 321 'tips': 'plugins/tooltips.js', 'svgdata': 'plugins/svgdata.js',
322 'electron': 'plugins/electron.js', 322 'electron': 'plugins/electron.js',
@@ -360,7 +360,7 @@ App.publicPlugin = [ @@ -360,7 +360,7 @@ App.publicPlugin = [
360 App.loadScripts = function(scripts, onload) 360 App.loadScripts = function(scripts, onload)
361 { 361 {
362 var n = scripts.length; 362 var n = scripts.length;
363 - 363 +
364 for (var i = 0; i < scripts.length; i++) 364 for (var i = 0; i < scripts.length; i++)
365 { 365 {
366 mxscript(scripts[i], function() 366 mxscript(scripts[i], function()
@@ -375,34 +375,34 @@ App.loadScripts = function(scripts, onload) @@ -375,34 +375,34 @@ App.loadScripts = function(scripts, onload)
375 375
376 /** 376 /**
377 * Function: getStoredMode 377 * Function: getStoredMode
378 - * 378 + *
379 * Returns the current mode. 379 * Returns the current mode.
380 */ 380 */
381 App.getStoredMode = function() 381 App.getStoredMode = function()
382 { 382 {
383 var mode = null; 383 var mode = null;
384 - 384 +
385 if (mode == null && isLocalStorage) 385 if (mode == null && isLocalStorage)
386 { 386 {
387 mode = localStorage.getItem('.mode'); 387 mode = localStorage.getItem('.mode');
388 } 388 }
389 - 389 +
390 if (mode == null && typeof(Storage) != 'undefined') 390 if (mode == null && typeof(Storage) != 'undefined')
391 { 391 {
392 var cookies = document.cookie.split(";"); 392 var cookies = document.cookie.split(";");
393 - 393 +
394 for (var i = 0; i < cookies.length; i++) 394 for (var i = 0; i < cookies.length; i++)
395 { 395 {
396 // Removes spaces around cookie 396 // Removes spaces around cookie
397 var cookie = mxUtils.trim(cookies[i]); 397 var cookie = mxUtils.trim(cookies[i]);
398 - 398 +
399 if (cookie.substring(0, 5) == 'MODE=') 399 if (cookie.substring(0, 5) == 'MODE=')
400 { 400 {
401 mode = cookie.substring(5); 401 mode = cookie.substring(5);
402 break; 402 break;
403 } 403 }
404 } 404 }
405 - 405 +
406 if (mode != null && isLocalStorage) 406 if (mode != null && isLocalStorage)
407 { 407 {
408 // Moves to local storage 408 // Moves to local storage
@@ -412,7 +412,7 @@ App.getStoredMode = function() @@ -412,7 +412,7 @@ App.getStoredMode = function()
412 localStorage.setItem('.mode', mode); 412 localStorage.setItem('.mode', mode);
413 } 413 }
414 } 414 }
415 - 415 +
416 return mode; 416 return mode;
417 }; 417 };
418 418
@@ -430,16 +430,16 @@ App.getStoredMode = function() @@ -430,16 +430,16 @@ App.getStoredMode = function()
430 { 430 {
431 urlParams['mode'] = 'dropbox'; 431 urlParams['mode'] = 'dropbox';
432 } 432 }
433 - 433 +
434 App.mode = urlParams['mode']; 434 App.mode = urlParams['mode'];
435 } 435 }
436 - 436 +
437 if (App.mode == null) 437 if (App.mode == null)
438 { 438 {
439 // Stored mode overrides preferred mode 439 // Stored mode overrides preferred mode
440 App.mode = App.getStoredMode(); 440 App.mode = App.getStoredMode();
441 } 441 }
442 - 442 +
443 /** 443 /**
444 * Lazy loading backends. 444 * Lazy loading backends.
445 */ 445 */
@@ -474,7 +474,7 @@ App.getStoredMode = function() @@ -474,7 +474,7 @@ App.getStoredMode = function()
474 window.DriveClient = null; 474 window.DriveClient = null;
475 } 475 }
476 } 476 }
477 - 477 +
478 // Loads dropbox for all browsers but IE8 and below (no CORS) if not disabled or if enabled and in embed mode 478 // Loads dropbox for all browsers but IE8 and below (no CORS) if not disabled or if enabled and in embed mode
479 // KNOWN: Picker does not work in IE11 (https://dropbox.zendesk.com/requests/1650781) 479 // KNOWN: Picker does not work in IE11 (https://dropbox.zendesk.com/requests/1650781)
480 if (typeof window.DropboxClient === 'function') 480 if (typeof window.DropboxClient === 'function')
@@ -490,7 +490,7 @@ App.getStoredMode = function() @@ -490,7 +490,7 @@ App.getStoredMode = function()
490 { 490 {
491 // Must load this after the dropbox SDK since they use the same namespace 491 // Must load this after the dropbox SDK since they use the same namespace
492 mxscript(App.DROPINS_URL, null, 'dropboxjs', App.DROPBOX_APPKEY, true); 492 mxscript(App.DROPINS_URL, null, 'dropboxjs', App.DROPBOX_APPKEY, true);
493 - }); 493 + });
494 } 494 }
495 else if (urlParams['chrome'] == '0') 495 else if (urlParams['chrome'] == '0')
496 { 496 {
@@ -503,7 +503,7 @@ App.getStoredMode = function() @@ -503,7 +503,7 @@ App.getStoredMode = function()
503 window.DropboxClient = null; 503 window.DropboxClient = null;
504 } 504 }
505 } 505 }
506 - 506 +
507 // Loads OneDrive for all browsers but IE6/IOS if not disabled or if enabled and in embed mode 507 // Loads OneDrive for all browsers but IE6/IOS if not disabled or if enabled and in embed mode
508 if (typeof window.OneDriveClient === 'function') 508 if (typeof window.OneDriveClient === 'function')
509 { 509 {
@@ -528,7 +528,7 @@ App.getStoredMode = function() @@ -528,7 +528,7 @@ App.getStoredMode = function()
528 window.OneDriveClient = null; 528 window.OneDriveClient = null;
529 } 529 }
530 } 530 }
531 - 531 +
532 // Loads Trello for all browsers but < IE10 if not disabled or if enabled and in embed mode 532 // Loads Trello for all browsers but < IE10 if not disabled or if enabled and in embed mode
533 if (typeof window.TrelloClient === 'function') 533 if (typeof window.TrelloClient === 'function')
534 { 534 {
@@ -584,7 +584,7 @@ App.clearServiceWorker = function(success) @@ -584,7 +584,7 @@ App.clearServiceWorker = function(success)
584 584
585 /** 585 /**
586 * Program flow starts here. 586 * Program flow starts here.
587 - * 587 + *
588 * Optional callback is called with the app instance. 588 * Optional callback is called with the app instance.
589 */ 589 */
590 let defHttp; 590 let defHttp;
@@ -613,28 +613,28 @@ App.main = function(callback, createUi) @@ -613,28 +613,28 @@ App.main = function(callback, createUi)
613 /aj\.draw\.io$/.test(window.location.hostname))) 613 /aj\.draw\.io$/.test(window.location.hostname)))
614 { 614 {
615 document.body.innerHTML = '<div style="margin-top:10%;text-align:center;">Stand-alone mode not allowed for this domain.</div>'; 615 document.body.innerHTML = '<div style="margin-top:10%;text-align:center;">Stand-alone mode not allowed for this domain.</div>';
616 - 616 +
617 return; 617 return;
618 } 618 }
619 - 619 +
620 // Removes info text in embed mode 620 // Removes info text in embed mode
621 if (urlParams['embed'] == '1' || urlParams['lightbox'] == '1') 621 if (urlParams['embed'] == '1' || urlParams['lightbox'] == '1')
622 { 622 {
623 var geInfo = document.getElementById('geInfo'); 623 var geInfo = document.getElementById('geInfo');
624 - 624 +
625 if (geInfo != null) 625 if (geInfo != null)
626 { 626 {
627 geInfo.parentNode.removeChild(geInfo); 627 geInfo.parentNode.removeChild(geInfo);
628 } 628 }
629 } 629 }
630 - 630 +
631 // Redirects to the latest AWS icons 631 // Redirects to the latest AWS icons
632 if (document.referrer != null && urlParams['libs'] == 'aws3' && 632 if (document.referrer != null && urlParams['libs'] == 'aws3' &&
633 document.referrer.substring(0, 42) == 'https://aws.amazon.com/architecture/icons/') 633 document.referrer.substring(0, 42) == 'https://aws.amazon.com/architecture/icons/')
634 { 634 {
635 urlParams['libs'] = 'aws4'; 635 urlParams['libs'] = 'aws4';
636 } 636 }
637 - 637 +
638 if (window.mxscript != null) 638 if (window.mxscript != null)
639 { 639 {
640 // Checks for script content changes to avoid CSP errors in production 640 // Checks for script content changes to avoid CSP errors in production
@@ -642,7 +642,7 @@ App.main = function(callback, createUi) @@ -642,7 +642,7 @@ App.main = function(callback, createUi)
642 CryptoJS != null && App.mode != App.MODE_DROPBOX && App.mode != App.MODE_TRELLO) 642 CryptoJS != null && App.mode != App.MODE_DROPBOX && App.mode != App.MODE_TRELLO)
643 { 643 {
644 var scripts = document.getElementsByTagName('script'); 644 var scripts = document.getElementsByTagName('script');
645 - 645 +
646 // Checks bootstrap script 646 // Checks bootstrap script
647 if (scripts != null && scripts.length > 0) 647 if (scripts != null && scripts.length > 0)
648 { 648 {
@@ -655,13 +655,14 @@ App.main = function(callback, createUi) @@ -655,13 +655,14 @@ App.main = function(callback, createUi)
655 alert('[Dev] Bootstrap script change requires update of CSP'); 655 alert('[Dev] Bootstrap script change requires update of CSP');
656 } 656 }
657 } 657 }
658 - 658 +
659 // Checks main script 659 // Checks main script
660 if (scripts != null && scripts.length > 1) 660 if (scripts != null && scripts.length > 1)
661 { 661 {
662 var content = mxUtils.getTextContent(scripts[scripts.length - 1]); 662 var content = mxUtils.getTextContent(scripts[scripts.length - 1]);
663 -  
664 - if (CryptoJS.MD5(content).toString() != 'd53805dd6f0bbba2da4966491ca0a505') 663 +
  664 + // if (CryptoJS.MD5(content).toString() != 'd53805dd6f0bbba2da4966491ca0a505')
  665 + if (CryptoJS.MD5(content).toString() != '4559a92176e60ec27e523711c8ea01ac')
665 { 666 {
666 console.log('Change main script MD5 in the previous line:', CryptoJS.MD5(content).toString()); 667 console.log('Change main script MD5 in the previous line:', CryptoJS.MD5(content).toString());
667 alert('[Dev] Main script change requires update of CSP'); 668 alert('[Dev] Main script change requires update of CSP');
@@ -697,7 +698,7 @@ App.main = function(callback, createUi) @@ -697,7 +698,7 @@ App.main = function(callback, createUi)
697 console.error(e); 698 console.error(e);
698 } 699 }
699 } 700 }
700 - 701 +
701 // Loads Pusher API 702 // Loads Pusher API
702 if (('ArrayBuffer' in window) && !mxClient.IS_CHROMEAPP && !EditorUi.isElectronApp && 703 if (('ArrayBuffer' in window) && !mxClient.IS_CHROMEAPP && !EditorUi.isElectronApp &&
703 DrawioFile.SYNC == 'auto' && (urlParams['embed'] != '1' || 704 DrawioFile.SYNC == 'auto' && (urlParams['embed'] != '1' ||
@@ -707,20 +708,20 @@ App.main = function(callback, createUi) @@ -707,20 +708,20 @@ App.main = function(callback, createUi)
707 { 708 {
708 // TODO: Check if async loading is fast enough 709 // TODO: Check if async loading is fast enough
709 mxscript(App.PUSHER_URL); 710 mxscript(App.PUSHER_URL);
710 - 711 +
711 if (urlParams['fast-sync'] == '1') 712 if (urlParams['fast-sync'] == '1')
712 { 713 {
713 mxscript(App.SIMPLE_PEER_URL); 714 mxscript(App.SIMPLE_PEER_URL);
714 } 715 }
715 } 716 }
716 - 717 +
717 // Loads plugins 718 // Loads plugins
718 if (urlParams['plugins'] != '0' && urlParams['offline'] != '1') 719 if (urlParams['plugins'] != '0' && urlParams['offline'] != '1')
719 { 720 {
720 // mxSettings is not yet initialized in configure mode, redirect parameter 721 // mxSettings is not yet initialized in configure mode, redirect parameter
721 // to p URL parameter in caller for plugins in embed mode 722 // to p URL parameter in caller for plugins in embed mode
722 var plugins = (mxSettings.settings != null) ? mxSettings.getPlugins() : null; 723 var plugins = (mxSettings.settings != null) ? mxSettings.getPlugins() : null;
723 - 724 +
724 // Configured plugins in embed mode with configure=1 URL should be loaded so we 725 // Configured plugins in embed mode with configure=1 URL should be loaded so we
725 // look ahead here and parse the config to fetch the list of custom plugins 726 // look ahead here and parse the config to fetch the list of custom plugins
726 if (mxSettings.settings == null && isLocalStorage && typeof(JSON) !== 'undefined') 727 if (mxSettings.settings == null && isLocalStorage && typeof(JSON) !== 'undefined')
@@ -728,7 +729,7 @@ App.main = function(callback, createUi) @@ -728,7 +729,7 @@ App.main = function(callback, createUi)
728 try 729 try
729 { 730 {
730 var temp = JSON.parse(localStorage.getItem(mxSettings.key)); 731 var temp = JSON.parse(localStorage.getItem(mxSettings.key));
731 - 732 +
732 if (temp != null) 733 if (temp != null)
733 { 734 {
734 plugins = temp.plugins; 735 plugins = temp.plugins;
@@ -748,15 +749,15 @@ App.main = function(callback, createUi) @@ -748,15 +749,15 @@ App.main = function(callback, createUi)
748 // Mapping from key to URL in App.plugins 749 // Mapping from key to URL in App.plugins
749 App.loadPlugins(temp.split(';')); 750 App.loadPlugins(temp.split(';'));
750 } 751 }
751 - 752 +
752 if (plugins != null && plugins.length > 0 && urlParams['plugins'] != '0') 753 if (plugins != null && plugins.length > 0 && urlParams['plugins'] != '0')
753 { 754 {
754 - // Loading plugins inside the asynchronous block below stops the page from loading so a 755 + // Loading plugins inside the asynchronous block below stops the page from loading so a
755 // hardcoded message for the warning dialog is used since the resources are loadd below 756 // hardcoded message for the warning dialog is used since the resources are loadd below
756 var warning = 'The page has requested to load the following plugin(s):\n \n {1}\n \n Would you like to load these plugin(s) now?\n \n NOTE : Only allow plugins to run if you fully understand the security implications of doing so.\n'; 757 var warning = 'The page has requested to load the following plugin(s):\n \n {1}\n \n Would you like to load these plugin(s) now?\n \n NOTE : Only allow plugins to run if you fully understand the security implications of doing so.\n';
757 var tmp = window.location.protocol + '//' + window.location.host; 758 var tmp = window.location.protocol + '//' + window.location.host;
758 var local = true; 759 var local = true;
759 - 760 +
760 for (var i = 0; i < plugins.length && local; i++) 761 for (var i = 0; i < plugins.length && local; i++)
761 { 762 {
762 if (plugins[i].charAt(0) != '/' && plugins[i].substring(0, tmp.length) != tmp) 763 if (plugins[i].charAt(0) != '/' && plugins[i].substring(0, tmp.length) != tmp)
@@ -764,7 +765,7 @@ App.main = function(callback, createUi) @@ -764,7 +765,7 @@ App.main = function(callback, createUi)
764 local = false; 765 local = false;
765 } 766 }
766 } 767 }
767 - 768 +
768 if (local || mxUtils.confirm(mxResources.replacePlaceholders(warning, [plugins.join('\n')]).replace(/\\n/g, '\n'))) 769 if (local || mxUtils.confirm(mxResources.replacePlaceholders(warning, [plugins.join('\n')]).replace(/\\n/g, '\n')))
769 { 770 {
770 for (var i = 0; i < plugins.length; i++) 771 for (var i = 0; i < plugins.length; i++)
@@ -775,12 +776,12 @@ App.main = function(callback, createUi) @@ -775,12 +776,12 @@ App.main = function(callback, createUi)
775 { 776 {
776 App.pluginsLoaded[plugins[i]] = true; 777 App.pluginsLoaded[plugins[i]] = true;
777 App.embedModePluginsCount++; 778 App.embedModePluginsCount++;
778 - 779 +
779 if (plugins[i].charAt(0) == '/') 780 if (plugins[i].charAt(0) == '/')
780 { 781 {
781 plugins[i] = PLUGINS_BASE_PATH + plugins[i]; 782 plugins[i] = PLUGINS_BASE_PATH + plugins[i];
782 } 783 }
783 - 784 +
784 mxscript(plugins[i]); 785 mxscript(plugins[i]);
785 } 786 }
786 } 787 }
@@ -792,7 +793,7 @@ App.main = function(callback, createUi) @@ -792,7 +793,7 @@ App.main = function(callback, createUi)
792 } 793 }
793 } 794 }
794 } 795 }
795 - 796 +
796 // Loads gapi for all browsers but IE8 and below if not disabled or if enabled and in embed mode 797 // Loads gapi for all browsers but IE8 and below if not disabled or if enabled and in embed mode
797 // Special case: Cannot load in asynchronous code below 798 // Special case: Cannot load in asynchronous code below
798 if (typeof window.DriveClient === 'function' && 799 if (typeof window.DriveClient === 'function' &&
@@ -808,7 +809,7 @@ App.main = function(callback, createUi) @@ -808,7 +809,7 @@ App.main = function(callback, createUi)
808 window.DriveClient = null; 809 window.DriveClient = null;
809 } 810 }
810 } 811 }
811 - 812 +
812 /** 813 /**
813 * Asynchronous MathJax extension. 814 * Asynchronous MathJax extension.
814 */ 815 */
@@ -827,7 +828,7 @@ App.main = function(callback, createUi) @@ -827,7 +828,7 @@ App.main = function(callback, createUi)
827 { 828 {
828 // Adds bundle text to resources 829 // Adds bundle text to resources
829 mxResources.parse(xhr[0].getText()); 830 mxResources.parse(xhr[0].getText());
830 - 831 +
831 // Configuration mode 832 // Configuration mode
832 if (isLocalStorage && localStorage != null && window.location.hash != null && 833 if (isLocalStorage && localStorage != null && window.location.hash != null &&
833 window.location.hash.substring(0, 9) == '#_CONFIG_') 834 window.location.hash.substring(0, 9) == '#_CONFIG_')
@@ -835,12 +836,12 @@ App.main = function(callback, createUi) @@ -835,12 +836,12 @@ App.main = function(callback, createUi)
835 try 836 try
836 { 837 {
837 var trustedPlugins = {}; 838 var trustedPlugins = {};
838 - 839 +
839 for (var key in App.pluginRegistry) 840 for (var key in App.pluginRegistry)
840 { 841 {
841 trustedPlugins[App.pluginRegistry[key]] = true; 842 trustedPlugins[App.pluginRegistry[key]] = true;
842 } 843 }
843 - 844 +
844 // Only allows trusted plugins 845 // Only allows trusted plugins
845 function checkPlugins(plugins) 846 function checkPlugins(plugins)
846 { 847 {
@@ -854,46 +855,46 @@ App.main = function(callback, createUi) @@ -854,46 +855,46 @@ App.main = function(callback, createUi)
854 } 855 }
855 } 856 }
856 } 857 }
857 - 858 +
858 return true; 859 return true;
859 }; 860 };
860 - 861 +
861 var value = JSON.parse(Graph.decompress(window.location.hash.substring(9))); 862 var value = JSON.parse(Graph.decompress(window.location.hash.substring(9)));
862 863
863 if (value != null && checkPlugins(value.plugins)) 864 if (value != null && checkPlugins(value.plugins))
864 { 865 {
865 EditorUi.debug('Setting configuration', JSON.stringify(value)); 866 EditorUi.debug('Setting configuration', JSON.stringify(value));
866 - 867 +
867 if (value.merge != null) 868 if (value.merge != null)
868 { 869 {
869 var temp = localStorage.getItem(Editor.configurationKey); 870 var temp = localStorage.getItem(Editor.configurationKey);
870 - 871 +
871 if (temp != null) 872 if (temp != null)
872 { 873 {
873 - 874 +
874 try 875 try
875 { 876 {
876 var config = JSON.parse(temp); 877 var config = JSON.parse(temp);
877 - 878 +
878 for (var key in value.merge) 879 for (var key in value.merge)
879 { 880 {
880 config[key] = value.merge[key]; 881 config[key] = value.merge[key];
881 } 882 }
882 -  
883 - value = config; 883 +
  884 + value = config;
884 } 885 }
885 catch (e) 886 catch (e)
886 { 887 {
887 window.location.hash = ''; 888 window.location.hash = '';
888 alert(e); 889 alert(e);
889 - } 890 + }
890 } 891 }
891 else 892 else
892 { 893 {
893 value = value.merge; 894 value = value.merge;
894 } 895 }
895 } 896 }
896 - 897 +
897 if (confirm(mxResources.get('configLinkWarn')) && 898 if (confirm(mxResources.get('configLinkWarn')) &&
898 confirm(mxResources.get('configLinkConfirm'))) 899 confirm(mxResources.get('configLinkConfirm')))
899 { 900 {
@@ -911,21 +912,21 @@ App.main = function(callback, createUi) @@ -911,21 +912,21 @@ App.main = function(callback, createUi)
911 alert(e); 912 alert(e);
912 } 913 }
913 } 914 }
914 - 915 +
915 // Prepares themes with mapping from old default-style to old XML file 916 // Prepares themes with mapping from old default-style to old XML file
916 if (xhr.length > 1) 917 if (xhr.length > 1)
917 { 918 {
918 Graph.prototype.defaultThemes['default-style2'] = xhr[1].getDocumentElement(); 919 Graph.prototype.defaultThemes['default-style2'] = xhr[1].getDocumentElement();
919 Graph.prototype.defaultThemes['darkTheme'] = xhr[1].getDocumentElement(); 920 Graph.prototype.defaultThemes['darkTheme'] = xhr[1].getDocumentElement();
920 } 921 }
921 - 922 +
922 // Main 923 // Main
923 function realMain() 924 function realMain()
924 { 925 {
925 var ui = (createUi != null) ? createUi() : new App(new Editor( 926 var ui = (createUi != null) ? createUi() : new App(new Editor(
926 urlParams['chrome'] == '0' || uiTheme == 'min', 927 urlParams['chrome'] == '0' || uiTheme == 'min',
927 null, null, null, urlParams['chrome'] != '0')); 928 null, null, null, urlParams['chrome'] != '0'));
928 - 929 +
929 if (window.mxscript != null) 930 if (window.mxscript != null)
930 { 931 {
931 // Loads dropbox for all browsers but IE8 and below (no CORS) if not disabled or if enabled and in embed mode 932 // Loads dropbox for all browsers but IE8 and below (no CORS) if not disabled or if enabled and in embed mode
@@ -950,7 +951,7 @@ App.main = function(callback, createUi) @@ -950,7 +951,7 @@ App.main = function(callback, createUi)
950 { 951 {
951 window.DropboxClient = null; 952 window.DropboxClient = null;
952 } 953 }
953 - 954 +
954 // Loads OneDrive for all browsers but IE6/IOS if not disabled or if enabled and in embed mode 955 // Loads OneDrive for all browsers but IE6/IOS if not disabled or if enabled and in embed mode
955 if (typeof window.OneDriveClient === 'function' && 956 if (typeof window.OneDriveClient === 'function' &&
956 (typeof OneDrive === 'undefined' && window.DrawOneDriveClientCallback != null && 957 (typeof OneDrive === 'undefined' && window.DrawOneDriveClientCallback != null &&
@@ -966,7 +967,7 @@ App.main = function(callback, createUi) @@ -966,7 +967,7 @@ App.main = function(callback, createUi)
966 { 967 {
967 window.OneDriveClient = null; 968 window.OneDriveClient = null;
968 } 969 }
969 - 970 +
970 // Loads Trello for all browsers but < IE10 if not disabled or if enabled and in embed mode 971 // Loads Trello for all browsers but < IE10 if not disabled or if enabled and in embed mode
971 if (typeof window.TrelloClient === 'function' && !mxClient.IS_IE11 && 972 if (typeof window.TrelloClient === 'function' && !mxClient.IS_IE11 &&
972 typeof window.Trello === 'undefined' && window.DrawTrelloClientCallback != null && 973 typeof window.Trello === 'undefined' && window.DrawTrelloClientCallback != null &&
@@ -987,28 +988,28 @@ App.main = function(callback, createUi) @@ -987,28 +988,28 @@ App.main = function(callback, createUi)
987 { 988 {
988 window.TrelloClient = null; 989 window.TrelloClient = null;
989 } 990 }
990 - 991 +
991 } 992 }
992 - 993 +
993 if (callback != null) 994 if (callback != null)
994 { 995 {
995 callback(ui); 996 callback(ui);
996 } 997 }
997 - 998 +
998 /** 999 /**
999 * For developers only 1000 * For developers only
1000 */ 1001 */
1001 if (urlParams['chrome'] != '0' && urlParams['test'] == '1') 1002 if (urlParams['chrome'] != '0' && urlParams['test'] == '1')
1002 { 1003 {
1003 EditorUi.debug('App.start', [ui, (new Date().getTime() - t0.getTime()) + 'ms']); 1004 EditorUi.debug('App.start', [ui, (new Date().getTime() - t0.getTime()) + 'ms']);
1004 - 1005 +
1005 if (urlParams['export'] != null) 1006 if (urlParams['export'] != null)
1006 { 1007 {
1007 EditorUi.debug('Export:', EXPORT_URL); 1008 EditorUi.debug('Export:', EXPORT_URL);
1008 } 1009 }
1009 } 1010 }
1010 }; 1011 };
1011 - 1012 +
1012 if (urlParams['dev'] == '1' || EditorUi.isElectronApp) //TODO check if we can remove these scripts loading from index.html 1013 if (urlParams['dev'] == '1' || EditorUi.isElectronApp) //TODO check if we can remove these scripts loading from index.html
1013 { 1014 {
1014 realMain(); 1015 realMain();
@@ -1022,11 +1023,11 @@ App.main = function(callback, createUi) @@ -1022,11 +1023,11 @@ App.main = function(callback, createUi)
1022 }, function(xhr) 1023 }, function(xhr)
1023 { 1024 {
1024 var st = document.getElementById('geStatus'); 1025 var st = document.getElementById('geStatus');
1025 - 1026 +
1026 if (st != null) 1027 if (st != null)
1027 { 1028 {
1028 st.innerHTML = 'Error loading page. <a>Please try refreshing.</a>'; 1029 st.innerHTML = 'Error loading page. <a>Please try refreshing.</a>';
1029 - 1030 +
1030 // Tries reload with default resources in case any language resources were not available 1031 // Tries reload with default resources in case any language resources were not available
1031 st.getElementsByTagName('a')[0].onclick = function() 1032 st.getElementsByTagName('a')[0].onclick = function()
1032 { 1033 {
@@ -1047,11 +1048,11 @@ App.main = function(callback, createUi) @@ -1047,11 +1048,11 @@ App.main = function(callback, createUi)
1047 { 1048 {
1048 document.body.style.backgroundColor = (uiTheme == 'dark' || 1049 document.body.style.backgroundColor = (uiTheme == 'dark' ||
1049 mxSettings.settings.darkMode) ? Editor.darkColor : '#ffffff'; 1050 mxSettings.settings.darkMode) ? Editor.darkColor : '#ffffff';
1050 - 1051 +
1051 if (mxSettings.settings.autosaveDelay != null) 1052 if (mxSettings.settings.autosaveDelay != null)
1052 { 1053 {
1053 var val = parseInt(mxSettings.settings.autosaveDelay); 1054 var val = parseInt(mxSettings.settings.autosaveDelay);
1054 - 1055 +
1055 if (!isNaN(val) && val > 0) 1056 if (!isNaN(val) && val > 0)
1056 { 1057 {
1057 DrawioFile.prototype.autosaveDelay = val; 1058 DrawioFile.prototype.autosaveDelay = val;
@@ -1062,11 +1063,11 @@ App.main = function(callback, createUi) @@ -1062,11 +1063,11 @@ App.main = function(callback, createUi)
1062 EditorUi.debug('Invalid autosaveDelay', val); 1063 EditorUi.debug('Invalid autosaveDelay', val);
1063 } 1064 }
1064 } 1065 }
1065 - 1066 +
1066 if (mxSettings.settings.defaultEdgeLength != null) 1067 if (mxSettings.settings.defaultEdgeLength != null)
1067 { 1068 {
1068 var val = parseInt(mxSettings.settings.defaultEdgeLength); 1069 var val = parseInt(mxSettings.settings.defaultEdgeLength);
1069 - 1070 +
1070 if (!isNaN(val) && val > 0) 1071 if (!isNaN(val) && val > 0)
1071 { 1072 {
1072 Graph.prototype.defaultEdgeLength = val; 1073 Graph.prototype.defaultEdgeLength = val;
@@ -1093,7 +1094,7 @@ App.main = function(callback, createUi) @@ -1093,7 +1094,7 @@ App.main = function(callback, createUi)
1093 for (var i = 0; i < Menus.prototype.defaultFonts.length; i++) 1094 for (var i = 0; i < Menus.prototype.defaultFonts.length; i++)
1094 { 1095 {
1095 var value = Menus.prototype.defaultFonts[i]; 1096 var value = Menus.prototype.defaultFonts[i];
1096 - 1097 +
1097 if (typeof value !== 'string' && 1098 if (typeof value !== 'string' &&
1098 value.fontFamily != null && 1099 value.fontFamily != null &&
1099 value.fontUrl != null) 1100 value.fontUrl != null)
@@ -1102,7 +1103,7 @@ App.main = function(callback, createUi) @@ -1102,7 +1103,7 @@ App.main = function(callback, createUi)
1102 } 1103 }
1103 } 1104 }
1104 } 1105 }
1105 - 1106 +
1106 // Adds required resources (disables loading of fallback properties, this can only 1107 // Adds required resources (disables loading of fallback properties, this can only
1107 // be used if we know that all keys are defined in the language specific file) 1108 // be used if we know that all keys are defined in the language specific file)
1108 mxResources.loadDefaultBundle = false; 1109 mxResources.loadDefaultBundle = false;
@@ -1114,7 +1115,7 @@ App.main = function(callback, createUi) @@ -1114,7 +1115,7 @@ App.main = function(callback, createUi)
1114 if (urlParams['configure'] == '1') 1115 if (urlParams['configure'] == '1')
1115 { 1116 {
1116 var op = window.opener || window.parent; 1117 var op = window.opener || window.parent;
1117 - 1118 +
1118 var configHandler = function(evt) 1119 var configHandler = function(evt)
1119 { 1120 {
1120 if (evt.source == op) 1121 if (evt.source == op)
@@ -1122,7 +1123,7 @@ App.main = function(callback, createUi) @@ -1122,7 +1123,7 @@ App.main = function(callback, createUi)
1122 try 1123 try
1123 { 1124 {
1124 var data = JSON.parse(evt.data); 1125 var data = JSON.parse(evt.data);
1125 - 1126 +
1126 if (data != null && data.action == 'configure') 1127 if (data != null && data.action == 'configure')
1127 { 1128 {
1128 mxEvent.removeListener(window, 'message', configHandler); 1129 mxEvent.removeListener(window, 'message', configHandler);
@@ -1140,7 +1141,7 @@ App.main = function(callback, createUi) @@ -1140,7 +1141,7 @@ App.main = function(callback, createUi)
1140 } 1141 }
1141 } 1142 }
1142 }; 1143 };
1143 - 1144 +
1144 // Receives XML message from opener and puts it into the graph 1145 // Receives XML message from opener and puts it into the graph
1145 mxEvent.addListener(window, 'message', configHandler); 1146 mxEvent.addListener(window, 'message', configHandler);
1146 op.postMessage(JSON.stringify({event: 'configure'}), '*'); 1147 op.postMessage(JSON.stringify({event: 'configure'}), '*');
@@ -1166,18 +1167,18 @@ App.main = function(callback, createUi) @@ -1166,18 +1167,18 @@ App.main = function(callback, createUi)
1166 } 1167 }
1167 } 1168 }
1168 } 1169 }
1169 - 1170 +
1170 // Loads configuration from local storage 1171 // Loads configuration from local storage
1171 if (isLocalStorage && localStorage != null && urlParams['embed'] != '1') 1172 if (isLocalStorage && localStorage != null && urlParams['embed'] != '1')
1172 { 1173 {
1173 var configData = localStorage.getItem(Editor.configurationKey); 1174 var configData = localStorage.getItem(Editor.configurationKey);
1174 - 1175 +
1175 if (configData != null) 1176 if (configData != null)
1176 { 1177 {
1177 try 1178 try
1178 { 1179 {
1179 configData = JSON.parse(configData); 1180 configData = JSON.parse(configData);
1180 - 1181 +
1181 if (configData != null) 1182 if (configData != null)
1182 { 1183 {
1183 EditorUi.debug('Using local configuration', configData); 1184 EditorUi.debug('Using local configuration', configData);
@@ -1195,7 +1196,7 @@ App.main = function(callback, createUi) @@ -1195,7 +1196,7 @@ App.main = function(callback, createUi)
1195 } 1196 }
1196 } 1197 }
1197 } 1198 }
1198 - 1199 +
1199 doMain(); 1200 doMain();
1200 } 1201 }
1201 }; 1202 };
@@ -1209,7 +1210,7 @@ mxUtils.extend(App, EditorUi); @@ -1209,7 +1210,7 @@ mxUtils.extend(App, EditorUi);
1209 App.prototype.defaultUserPicture = IMAGE_PATH + '/default-user.jpg'; 1210 App.prototype.defaultUserPicture = IMAGE_PATH + '/default-user.jpg';
1210 1211
1211 /** 1212 /**
1212 - * 1213 + *
1213 */ 1214 */
1214 App.prototype.shareImage = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA2RpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYwIDYxLjEzNDc3NywgMjAxMC8wMi8xMi0xNzozMjowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDowOTgwMTE3NDA3MjA2ODExODhDNkFGMDBEQkQ0RTgwOSIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDoxMjU2NzdEMTcwRDIxMUUxQjc0MDkxRDhCNUQzOEFGRCIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDoxMjU2NzdEMDcwRDIxMUUxQjc0MDkxRDhCNUQzOEFGRCIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ1M1IFdpbmRvd3MiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDowNjgwMTE3NDA3MjA2ODExODcxRkM4MUY1OTFDMjQ5OCIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDowNzgwMTE3NDA3MjA2ODExODhDNkFGMDBEQkQ0RTgwOSIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PrM/fs0AAADgSURBVHjaYmDAA/7//88MwgzkAKDGFiD+BsQ/QWxSNaf9RwN37twpI8WAS+gGfP78+RpQSoRYA36iG/D379+vQClNdLVMOMz4gi7w79+/n0CKg1gD9qELvH379hzIHGK9oA508ieY8//8+fO5rq4uFCilRKwL1JmYmNhhHEZGRiZ+fn6Q2meEbDYG4u3/cYCfP38uA7kOm0ZOIJ7zn0jw48ePPiDFhmzArv8kgi9fvuwB+w5qwH9ykjswbFSZyM4sEMDPBDTlL5BxkFSd7969OwZ2BZKYGhDzkmjOJ4AAAwBhpRqGnEFb8QAAAABJRU5ErkJggg=='; 1215 App.prototype.shareImage = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA2RpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYwIDYxLjEzNDc3NywgMjAxMC8wMi8xMi0xNzozMjowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDowOTgwMTE3NDA3MjA2ODExODhDNkFGMDBEQkQ0RTgwOSIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDoxMjU2NzdEMTcwRDIxMUUxQjc0MDkxRDhCNUQzOEFGRCIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDoxMjU2NzdEMDcwRDIxMUUxQjc0MDkxRDhCNUQzOEFGRCIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ1M1IFdpbmRvd3MiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDowNjgwMTE3NDA3MjA2ODExODcxRkM4MUY1OTFDMjQ5OCIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDowNzgwMTE3NDA3MjA2ODExODhDNkFGMDBEQkQ0RTgwOSIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PrM/fs0AAADgSURBVHjaYmDAA/7//88MwgzkAKDGFiD+BsQ/QWxSNaf9RwN37twpI8WAS+gGfP78+RpQSoRYA36iG/D379+vQClNdLVMOMz4gi7w79+/n0CKg1gD9qELvH379hzIHGK9oA508ieY8//8+fO5rq4uFCilRKwL1JmYmNhhHEZGRiZ+fn6Q2meEbDYG4u3/cYCfP38uA7kOm0ZOIJ7zn0jw48ePPiDFhmzArv8kgi9fvuwB+w5qwH9ykjswbFSZyM4sEMDPBDTlL5BxkFSd7969OwZ2BZKYGhDzkmjOJ4AAAwBhpRqGnEFb8QAAAABJRU5ErkJggg==';
1215 1216
@@ -1253,7 +1254,7 @@ App.prototype.compactMode = false; @@ -1253,7 +1254,7 @@ App.prototype.compactMode = false;
1253 * 1254 *
1254 */ 1255 */
1255 App.prototype.fullscreenMode = false; 1256 App.prototype.fullscreenMode = false;
1256 - 1257 +
1257 /** 1258 /**
1258 * Overriden UI settings depending on mode. 1259 * Overriden UI settings depending on mode.
1259 */ 1260 */
@@ -1275,7 +1276,7 @@ App.initPluginCallback = function() @@ -1275,7 +1276,7 @@ App.initPluginCallback = function()
1275 { 1276 {
1276 // Workaround for need to load plugins now but wait for UI instance 1277 // Workaround for need to load plugins now but wait for UI instance
1277 App.DrawPlugins = []; 1278 App.DrawPlugins = [];
1278 - 1279 +
1279 // Global entry point for plugins is Draw.loadPlugin. This is the only 1280 // Global entry point for plugins is Draw.loadPlugin. This is the only
1280 // long-term supported solution for access to the EditorUi instance. 1281 // long-term supported solution for access to the EditorUi instance.
1281 window.Draw = new Object(); 1282 window.Draw = new Object();
@@ -1287,7 +1288,7 @@ App.initPluginCallback = function() @@ -1287,7 +1288,7 @@ App.initPluginCallback = function()
1287 }; 1288 };
1288 1289
1289 /** 1290 /**
1290 - * 1291 + *
1291 */ 1292 */
1292 App.pluginsLoaded = {}; 1293 App.pluginsLoaded = {};
1293 App.embedModePluginsCount = 0; 1294 App.embedModePluginsCount = 0;
@@ -1306,14 +1307,14 @@ App.loadPlugins = function(plugins, useInclude) @@ -1306,14 +1307,14 @@ App.loadPlugins = function(plugins, useInclude)
1306 try 1307 try
1307 { 1308 {
1308 var url = PLUGINS_BASE_PATH + App.pluginRegistry[plugins[i]]; 1309 var url = PLUGINS_BASE_PATH + App.pluginRegistry[plugins[i]];
1309 - 1310 +
1310 if (url != null) 1311 if (url != null)
1311 { 1312 {
1312 if (App.pluginsLoaded[url] == null) 1313 if (App.pluginsLoaded[url] == null)
1313 { 1314 {
1314 App.pluginsLoaded[url] = true; 1315 App.pluginsLoaded[url] = true;
1315 App.embedModePluginsCount++; 1316 App.embedModePluginsCount++;
1316 - 1317 +
1317 if (typeof window.drawDevUrl === 'undefined') 1318 if (typeof window.drawDevUrl === 'undefined')
1318 { 1319 {
1319 if (useInclude) 1320 if (useInclude)
@@ -1366,7 +1367,7 @@ App.prototype.initializeEmbedMode = function() @@ -1366,7 +1367,7 @@ App.prototype.initializeEmbedMode = function()
1366 { 1367 {
1367 this.showBanner('EmbedDeprecationFooter', 'app.diagrams.net will stop working for embed mode. Please use embed.diagrams.net.'); 1368 this.showBanner('EmbedDeprecationFooter', 'app.diagrams.net will stop working for embed mode. Please use embed.diagrams.net.');
1368 } 1369 }
1369 - 1370 +
1370 if (App.embedModePluginsCount > 0 || this.initEmbedDone) 1371 if (App.embedModePluginsCount > 0 || this.initEmbedDone)
1371 { 1372 {
1372 return; //Wait for plugins to load, or this is a duplicate call due to timeout 1373 return; //Wait for plugins to load, or this is a duplicate call due to timeout
@@ -1375,7 +1376,7 @@ App.prototype.initializeEmbedMode = function() @@ -1375,7 +1376,7 @@ App.prototype.initializeEmbedMode = function()
1375 { 1376 {
1376 this.initEmbedDone = true; 1377 this.initEmbedDone = true;
1377 } 1378 }
1378 - 1379 +
1379 EditorUi.prototype.initializeEmbedMode.apply(this, arguments); 1380 EditorUi.prototype.initializeEmbedMode.apply(this, arguments);
1380 } 1381 }
1381 }; 1382 };
@@ -1413,7 +1414,7 @@ App.prototype.init = function() @@ -1413,7 +1414,7 @@ App.prototype.init = function()
1413 1414
1414 /** 1415 /**
1415 * Holds the listener for description changes. 1416 * Holds the listener for description changes.
1416 - */ 1417 + */
1417 this.descriptorChangedListener = mxUtils.bind(this, this.descriptorChanged); 1418 this.descriptorChangedListener = mxUtils.bind(this, this.descriptorChanged);
1418 1419
1419 /** 1420 /**
@@ -1423,7 +1424,7 @@ App.prototype.init = function() @@ -1423,7 +1424,7 @@ App.prototype.init = function()
1423 mxClient.IS_IE11 || mxClient.IS_EDGE) && 1424 mxClient.IS_IE11 || mxClient.IS_EDGE) &&
1424 (urlParams['gh'] != '0' && (urlParams['embed'] != '1' || 1425 (urlParams['gh'] != '0' && (urlParams['embed'] != '1' ||
1425 urlParams['gh'] == '1')) ? new GitHubClient(this) : null; 1426 urlParams['gh'] == '1')) ? new GitHubClient(this) : null;
1426 - 1427 +
1427 if (this.gitHub != null) 1428 if (this.gitHub != null)
1428 { 1429 {
1429 this.gitHub.addListener('userChanged', mxUtils.bind(this, function() 1430 this.gitHub.addListener('userChanged', mxUtils.bind(this, function()
@@ -1432,7 +1433,7 @@ App.prototype.init = function() @@ -1432,7 +1433,7 @@ App.prototype.init = function()
1432 this.restoreLibraries(); 1433 this.restoreLibraries();
1433 })); 1434 }));
1434 } 1435 }
1435 - 1436 +
1436 /** 1437 /**
1437 * Creates gitlab client. 1438 * Creates gitlab client.
1438 */ 1439 */
@@ -1466,13 +1467,13 @@ App.prototype.init = function() @@ -1466,13 +1467,13 @@ App.prototype.init = function()
1466 * Holds the x-coordinate of the point. 1467 * Holds the x-coordinate of the point.
1467 */ 1468 */
1468 this.oneDrive = new OneDriveClient(this); 1469 this.oneDrive = new OneDriveClient(this);
1469 - 1470 +
1470 this.oneDrive.addListener('userChanged', mxUtils.bind(this, function() 1471 this.oneDrive.addListener('userChanged', mxUtils.bind(this, function()
1471 { 1472 {
1472 this.updateUserElement(); 1473 this.updateUserElement();
1473 this.restoreLibraries(); 1474 this.restoreLibraries();
1474 })); 1475 }));
1475 - 1476 +
1476 // Notifies listeners of new client 1477 // Notifies listeners of new client
1477 this.fireEvent(new mxEventObject('clientLoaded', 'client', this.oneDrive)); 1478 this.fireEvent(new mxEventObject('clientLoaded', 'client', this.oneDrive));
1478 } 1479 }
@@ -1500,14 +1501,14 @@ App.prototype.init = function() @@ -1500,14 +1501,14 @@ App.prototype.init = function()
1500 try 1501 try
1501 { 1502 {
1502 this.trello = new TrelloClient(this); 1503 this.trello = new TrelloClient(this);
1503 - 1504 +
1504 //TODO we have no user info from Trello so we don't set a user 1505 //TODO we have no user info from Trello so we don't set a user
1505 this.trello.addListener('userChanged', mxUtils.bind(this, function() 1506 this.trello.addListener('userChanged', mxUtils.bind(this, function()
1506 { 1507 {
1507 this.updateUserElement(); 1508 this.updateUserElement();
1508 this.restoreLibraries(); 1509 this.restoreLibraries();
1509 })); 1510 }));
1510 - 1511 +
1511 // Notifies listeners of new client 1512 // Notifies listeners of new client
1512 this.fireEvent(new mxEventObject('clientLoaded', 'client', this.trello)); 1513 this.fireEvent(new mxEventObject('clientLoaded', 'client', this.trello));
1513 } 1514 }
@@ -1543,22 +1544,22 @@ App.prototype.init = function() @@ -1543,22 +1544,22 @@ App.prototype.init = function()
1543 var doInit = mxUtils.bind(this, function() 1544 var doInit = mxUtils.bind(this, function()
1544 { 1545 {
1545 this.drive = new DriveClient(this); 1546 this.drive = new DriveClient(this);
1546 - 1547 +
1547 this.drive.addListener('userChanged', mxUtils.bind(this, function() 1548 this.drive.addListener('userChanged', mxUtils.bind(this, function()
1548 { 1549 {
1549 this.updateUserElement(); 1550 this.updateUserElement();
1550 this.restoreLibraries(); 1551 this.restoreLibraries();
1551 this.checkLicense(); 1552 this.checkLicense();
1552 })) 1553 }))
1553 - 1554 +
1554 // Notifies listeners of new client 1555 // Notifies listeners of new client
1555 this.fireEvent(new mxEventObject('clientLoaded', 'client', this.drive)); 1556 this.fireEvent(new mxEventObject('clientLoaded', 'client', this.drive));
1556 }); 1557 });
1557 - 1558 +
1558 if (window.DrawGapiClientCallback != null) 1559 if (window.DrawGapiClientCallback != null)
1559 { 1560 {
1560 gapi.load(((urlParams['picker'] != '0') ? 'picker,': '') + App.GOOGLE_APIS, doInit); 1561 gapi.load(((urlParams['picker'] != '0') ? 'picker,': '') + App.GOOGLE_APIS, doInit);
1561 - 1562 +
1562 /** 1563 /**
1563 * Clears any callbacks. 1564 * Clears any callbacks.
1564 */ 1565 */
@@ -1574,7 +1575,7 @@ App.prototype.init = function() @@ -1574,7 +1575,7 @@ App.prototype.init = function()
1574 window.DrawGapiClientCallback = initDriveClient; 1575 window.DrawGapiClientCallback = initDriveClient;
1575 } 1576 }
1576 }); 1577 });
1577 - 1578 +
1578 initDriveClient(); 1579 initDriveClient();
1579 } 1580 }
1580 1581
@@ -1591,20 +1592,20 @@ App.prototype.init = function() @@ -1591,20 +1592,20 @@ App.prototype.init = function()
1591 * Clears dropbox client callback. 1592 * Clears dropbox client callback.
1592 */ 1593 */
1593 window.DrawDropboxClientCallback = null; 1594 window.DrawDropboxClientCallback = null;
1594 - 1595 +
1595 /** 1596 /**
1596 * Holds the x-coordinate of the point. 1597 * Holds the x-coordinate of the point.
1597 */ 1598 */
1598 try 1599 try
1599 { 1600 {
1600 this.dropbox = new DropboxClient(this); 1601 this.dropbox = new DropboxClient(this);
1601 - 1602 +
1602 this.dropbox.addListener('userChanged', mxUtils.bind(this, function() 1603 this.dropbox.addListener('userChanged', mxUtils.bind(this, function()
1603 { 1604 {
1604 this.updateUserElement(); 1605 this.updateUserElement();
1605 this.restoreLibraries(); 1606 this.restoreLibraries();
1606 })); 1607 }));
1607 - 1608 +
1608 // Notifies listeners of new client 1609 // Notifies listeners of new client
1609 this.fireEvent(new mxEventObject('clientLoaded', 'client', this.dropbox)); 1610 this.fireEvent(new mxEventObject('clientLoaded', 'client', this.dropbox));
1610 } 1611 }
@@ -1647,7 +1648,7 @@ App.prototype.init = function() @@ -1647,7 +1648,7 @@ App.prototype.init = function()
1647 { 1648 {
1648 this.mode = App.mode; 1649 this.mode = App.mode;
1649 } 1650 }
1650 - 1651 +
1651 // Add to Home Screen dialog for mobile devices 1652 // Add to Home Screen dialog for mobile devices
1652 if ('serviceWorker' in navigator && !this.editor.isChromelessView() && 1653 if ('serviceWorker' in navigator && !this.editor.isChromelessView() &&
1653 (mxClient.IS_ANDROID || mxClient.IS_IOS)) 1654 (mxClient.IS_ANDROID || mxClient.IS_IOS))
@@ -1660,7 +1661,7 @@ App.prototype.init = function() @@ -1660,7 +1661,7 @@ App.prototype.init = function()
1660 }); 1661 });
1661 })); 1662 }));
1662 } 1663 }
1663 - 1664 +
1664 if (!mxClient.IS_CHROMEAPP && !EditorUi.isElectronApp && !this.isOffline() && 1665 if (!mxClient.IS_CHROMEAPP && !EditorUi.isElectronApp && !this.isOffline() &&
1665 !mxClient.IS_ANDROID && !mxClient.IS_IOS && urlParams['open'] == null && 1666 !mxClient.IS_ANDROID && !mxClient.IS_IOS && urlParams['open'] == null &&
1666 (!this.editor.chromeless || this.editor.editable)) 1667 (!this.editor.chromeless || this.editor.editable))
@@ -1669,7 +1670,7 @@ App.prototype.init = function() @@ -1669,7 +1670,7 @@ App.prototype.init = function()
1669 { 1670 {
1670 var file = this.getCurrentFile(); 1671 var file = this.getCurrentFile();
1671 var mode = (file != null) ? file.getMode() : null; 1672 var mode = (file != null) ? file.getMode() : null;
1672 - 1673 +
1673 if (urlParams['extAuth'] != '1' && (mode == App.MODE_DEVICE || mode == App.MODE_BROWSER)) 1674 if (urlParams['extAuth'] != '1' && (mode == App.MODE_DEVICE || mode == App.MODE_BROWSER))
1674 { 1675 {
1675 //关闭桌面弹出广告 1676 //关闭桌面弹出广告
@@ -1683,38 +1684,38 @@ App.prototype.init = function() @@ -1683,38 +1684,38 @@ App.prototype.init = function()
1683 } 1684 }
1684 })); 1685 }));
1685 } 1686 }
1686 - 1687 +
1687 if (!mxClient.IS_CHROMEAPP && !EditorUi.isElectronApp && urlParams['embed'] != '1' && DrawioFile.SYNC == 'auto' && 1688 if (!mxClient.IS_CHROMEAPP && !EditorUi.isElectronApp && urlParams['embed'] != '1' && DrawioFile.SYNC == 'auto' &&
1688 urlParams['local'] != '1' && urlParams['stealth'] != '1' && !this.isOffline() && 1689 urlParams['local'] != '1' && urlParams['stealth'] != '1' && !this.isOffline() &&
1689 (!this.editor.chromeless || this.editor.editable)) 1690 (!this.editor.chromeless || this.editor.editable))
1690 { 1691 {
1691 // Checks if the cache is alive 1692 // Checks if the cache is alive
1692 var acceptResponse = true; 1693 var acceptResponse = true;
1693 - 1694 +
1694 var timeoutThread = window.setTimeout(mxUtils.bind(this, function() 1695 var timeoutThread = window.setTimeout(mxUtils.bind(this, function()
1695 { 1696 {
1696 acceptResponse = false; 1697 acceptResponse = false;
1697 - 1698 +
1698 // Switches to manual sync if cache cannot be reached 1699 // Switches to manual sync if cache cannot be reached
1699 DrawioFile.SYNC = 'manual'; 1700 DrawioFile.SYNC = 'manual';
1700 - 1701 +
1701 var file = this.getCurrentFile(); 1702 var file = this.getCurrentFile();
1702 - 1703 +
1703 if (file != null && file.sync != null) 1704 if (file != null && file.sync != null)
1704 { 1705 {
1705 file.sync.destroy(); 1706 file.sync.destroy();
1706 file.sync = null; 1707 file.sync = null;
1707 - 1708 +
1708 var status = mxUtils.htmlEntities(mxResources.get('timeout')); 1709 var status = mxUtils.htmlEntities(mxResources.get('timeout'));
1709 this.editor.setStatus('<div title="'+ status + 1710 this.editor.setStatus('<div title="'+ status +
1710 '" class="geStatusAlert">' + status + '</div>'); 1711 '" class="geStatusAlert">' + status + '</div>');
1711 } 1712 }
1712 - 1713 +
1713 EditorUi.logEvent({category: 'TIMEOUT-CACHE-CHECK', action: 'timeout', label: 408}); 1714 EditorUi.logEvent({category: 'TIMEOUT-CACHE-CHECK', action: 'timeout', label: 408});
1714 }), Editor.cacheTimeout); 1715 }), Editor.cacheTimeout);
1715 - 1716 +
1716 var t0 = new Date().getTime(); 1717 var t0 = new Date().getTime();
1717 - 1718 +
1718 mxUtils.get(EditorUi.cacheUrl + '?alive', mxUtils.bind(this, function(req) 1719 mxUtils.get(EditorUi.cacheUrl + '?alive', mxUtils.bind(this, function(req)
1719 { 1720 {
1720 window.clearTimeout(timeoutThread); 1721 window.clearTimeout(timeoutThread);
@@ -1735,7 +1736,7 @@ App.prototype.init = function() @@ -1735,7 +1736,7 @@ App.prototype.init = function()
1735 this.buttonContainer.style.paddingRight = '48px'; 1736 this.buttonContainer.style.paddingRight = '48px';
1736 this.buttonContainer.style.position = 'absolute'; 1737 this.buttonContainer.style.position = 'absolute';
1737 this.buttonContainer.style.right = '0px'; 1738 this.buttonContainer.style.right = '0px';
1738 - 1739 +
1739 this.menubar.container.appendChild(this.buttonContainer); 1740 this.menubar.container.appendChild(this.buttonContainer);
1740 } 1741 }
1741 1742
@@ -1746,21 +1747,21 @@ App.prototype.init = function() @@ -1746,21 +1747,21 @@ App.prototype.init = function()
1746 this.toggleElement.click(); 1747 this.toggleElement.click();
1747 this.toggleElement.style.display = 'none'; 1748 this.toggleElement.style.display = 'none';
1748 } 1749 }
1749 - 1750 +
1750 this.icon = document.createElement('img'); 1751 this.icon = document.createElement('img');
1751 this.icon.setAttribute('src', IMAGE_PATH + '/logo-flat-small.png'); 1752 this.icon.setAttribute('src', IMAGE_PATH + '/logo-flat-small.png');
1752 this.icon.setAttribute('title', mxResources.get('draw.io')); 1753 this.icon.setAttribute('title', mxResources.get('draw.io'));
1753 this.icon.style.padding = urlParams['atlas'] == '1'? '7px' : '6px'; 1754 this.icon.style.padding = urlParams['atlas'] == '1'? '7px' : '6px';
1754 this.icon.style.cursor = 'pointer'; 1755 this.icon.style.cursor = 'pointer';
1755 - 1756 +
1756 mxEvent.addListener(this.icon, 'click', mxUtils.bind(this, function(evt) 1757 mxEvent.addListener(this.icon, 'click', mxUtils.bind(this, function(evt)
1757 { 1758 {
1758 this.appIconClicked(evt); 1759 this.appIconClicked(evt);
1759 })); 1760 }));
1760 - 1761 +
1761 this.menubar.container.insertBefore(this.icon, this.menubar.container.firstChild); 1762 this.menubar.container.insertBefore(this.icon, this.menubar.container.firstChild);
1762 } 1763 }
1763 - 1764 +
1764 if (this.editor.graph.isViewer()) 1765 if (this.editor.graph.isViewer())
1765 { 1766 {
1766 this.initializeViewerMode(); 1767 this.initializeViewerMode();
@@ -1820,22 +1821,22 @@ App.prototype.sanityCheck = function() @@ -1820,22 +1821,22 @@ App.prototype.sanityCheck = function()
1820 '-change_' + ((file.lastChanged != null) ? Math.round((Date.now() - file.lastChanged.getTime()) / 1000) : 'x')+ 1821 '-change_' + ((file.lastChanged != null) ? Math.round((Date.now() - file.lastChanged.getTime()) / 1000) : 'x')+
1821 '-alive_' + Math.round((Date.now() - App.startTime.getTime()) / 1000), 1822 '-alive_' + Math.round((Date.now() - App.startTime.getTime()) / 1000),
1822 label: (file.sync != null) ? ('client_' + file.sync.clientId) : 'nosync'}; 1823 label: (file.sync != null) ? ('client_' + file.sync.clientId) : 'nosync'};
1823 - 1824 +
1824 if (file.constructor == DriveFile && file.desc != null && this.drive != null) 1825 if (file.constructor == DriveFile && file.desc != null && this.drive != null)
1825 { 1826 {
1826 evt.label += ((this.drive.user != null) ? ('-user_' + this.drive.user.id) : '-nouser') + '-rev_' + 1827 evt.label += ((this.drive.user != null) ? ('-user_' + this.drive.user.id) : '-nouser') + '-rev_' +
1827 file.desc.headRevisionId + '-mod_' + file.desc.modifiedDate + '-size_' + file.getSize() + 1828 file.desc.headRevisionId + '-mod_' + file.desc.modifiedDate + '-size_' + file.getSize() +
1828 '-mime_' + file.desc.mimeType; 1829 '-mime_' + file.desc.mimeType;
1829 } 1830 }
1830 - 1831 +
1831 EditorUi.logEvent(evt); 1832 EditorUi.logEvent(evt);
1832 1833
1833 var msg = mxResources.get('ensureDataSaved'); 1834 var msg = mxResources.get('ensureDataSaved');
1834 - 1835 +
1835 if (file.lastSaved != null) 1836 if (file.lastSaved != null)
1836 { 1837 {
1837 var str = this.timeSince(file.lastSaved); 1838 var str = this.timeSince(file.lastSaved);
1838 - 1839 +
1839 if (str == null) 1840 if (str == null)
1840 { 1841 {
1841 str = mxResources.get('lessThanAMinute'); 1842 str = mxResources.get('lessThanAMinute');
@@ -1843,7 +1844,7 @@ App.prototype.sanityCheck = function() @@ -1843,7 +1844,7 @@ App.prototype.sanityCheck = function()
1843 1844
1844 msg = mxResources.get('lastSaved', [str]); 1845 msg = mxResources.get('lastSaved', [str]);
1845 } 1846 }
1846 - 1847 +
1847 // Resets possible stale state 1848 // Resets possible stale state
1848 this.spinner.stop(); 1849 this.spinner.stop();
1849 1850
@@ -1889,7 +1890,7 @@ App.prototype.getPusher = function() @@ -1889,7 +1890,7 @@ App.prototype.getPusher = function()
1889 encrypted: true 1890 encrypted: true
1890 }); 1891 });
1891 } 1892 }
1892 - 1893 +
1893 return this.pusher; 1894 return this.pusher;
1894 }; 1895 };
1895 1896
@@ -1942,14 +1943,14 @@ App.prototype.showRatingBanner = function() @@ -1942,14 +1943,14 @@ App.prototype.showRatingBanner = function()
1942 mxUtils.setPrefixedStyle(banner.style, 'transform', 'translate(-50%,120%)'); 1943 mxUtils.setPrefixedStyle(banner.style, 'transform', 'translate(-50%,120%)');
1943 mxUtils.setPrefixedStyle(banner.style, 'transition', 'all 1s ease'); 1944 mxUtils.setPrefixedStyle(banner.style, 'transition', 'all 1s ease');
1944 banner.className = 'geBtn gePrimaryBtn'; 1945 banner.className = 'geBtn gePrimaryBtn';
1945 - 1946 +
1946 var img = document.createElement('img'); 1947 var img = document.createElement('img');
1947 img.setAttribute('src', Dialog.prototype.closeImage); 1948 img.setAttribute('src', Dialog.prototype.closeImage);
1948 img.setAttribute('title', mxResources.get('close')); 1949 img.setAttribute('title', mxResources.get('close'));
1949 img.setAttribute('border', '0'); 1950 img.setAttribute('border', '0');
1950 img.style.cssText = 'position:absolute;right:10px;top:12px;filter:invert(1);padding:6px;margin:-6px;cursor:default;'; 1951 img.style.cssText = 'position:absolute;right:10px;top:12px;filter:invert(1);padding:6px;margin:-6px;cursor:default;';
1951 banner.appendChild(img); 1952 banner.appendChild(img);
1952 - 1953 +
1953 var star = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAABx0RVh0U29mdHdhcmUAQWRvYmUgRmlyZ' + 1954 var star = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAABx0RVh0U29mdHdhcmUAQWRvYmUgRmlyZ' +
1954 'XdvcmtzIENTM5jWRgMAAAQRdEVYdFhNTDpjb20uYWRvYmUueG1wADw/eHBhY2tldCBiZWdpbj0iICAgIiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+Cjx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8i' + 1955 'XdvcmtzIENTM5jWRgMAAAQRdEVYdFhNTDpjb20uYWRvYmUueG1wADw/eHBhY2tldCBiZWdpbj0iICAgIiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+Cjx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8i' +
1955 'IHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDQuMS1jMDM0IDQ2LjI3Mjk3NiwgU2F0IEphbiAyNyAyMDA3IDIyOjExOjQxICAgICAgICAiPgogICA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDI' + 1956 'IHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDQuMS1jMDM0IDQ2LjI3Mjk3NiwgU2F0IEphbiAyNyAyMDA3IDIyOjExOjQxICAgICAgICAiPgogICA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDI' +
@@ -1967,7 +1968,7 @@ App.prototype.showRatingBanner = function() @@ -1967,7 +1968,7 @@ App.prototype.showRatingBanner = function()
1967 1968
1968 mxUtils.write(banner, 'Please rate us'); 1969 mxUtils.write(banner, 'Please rate us');
1969 document.body.appendChild(banner); 1970 document.body.appendChild(banner);
1970 - 1971 +
1971 var star1 = document.createElement('img'); 1972 var star1 = document.createElement('img');
1972 star1.setAttribute('border', '0'); 1973 star1.setAttribute('border', '0');
1973 star1.setAttribute('align', 'absmiddle'); 1974 star1.setAttribute('align', 'absmiddle');
@@ -1975,7 +1976,7 @@ App.prototype.showRatingBanner = function() @@ -1975,7 +1976,7 @@ App.prototype.showRatingBanner = function()
1975 star1.setAttribute('style', 'margin-top:-6px;cursor:pointer;margin-left:8px;'); 1976 star1.setAttribute('style', 'margin-top:-6px;cursor:pointer;margin-left:8px;');
1976 star1.setAttribute('src', star); 1977 star1.setAttribute('src', star);
1977 banner.appendChild(star1); 1978 banner.appendChild(star1);
1978 - 1979 +
1979 var star2 = document.createElement('img'); 1980 var star2 = document.createElement('img');
1980 star2.setAttribute('border', '0'); 1981 star2.setAttribute('border', '0');
1981 star2.setAttribute('align', 'absmiddle'); 1982 star2.setAttribute('align', 'absmiddle');
@@ -1983,7 +1984,7 @@ App.prototype.showRatingBanner = function() @@ -1983,7 +1984,7 @@ App.prototype.showRatingBanner = function()
1983 star2.setAttribute('style', 'margin-top:-6px;margin-left:3px;cursor:pointer;'); 1984 star2.setAttribute('style', 'margin-top:-6px;margin-left:3px;cursor:pointer;');
1984 star2.setAttribute('src', star); 1985 star2.setAttribute('src', star);
1985 banner.appendChild(star2); 1986 banner.appendChild(star2);
1986 - 1987 +
1987 var star3 = document.createElement('img'); 1988 var star3 = document.createElement('img');
1988 star3.setAttribute('border', '0'); 1989 star3.setAttribute('border', '0');
1989 star3.setAttribute('align', 'absmiddle'); 1990 star3.setAttribute('align', 'absmiddle');
@@ -1991,7 +1992,7 @@ App.prototype.showRatingBanner = function() @@ -1991,7 +1992,7 @@ App.prototype.showRatingBanner = function()
1991 star3.setAttribute('style', 'margin-top:-6px;margin-left:3px;cursor:pointer;'); 1992 star3.setAttribute('style', 'margin-top:-6px;margin-left:3px;cursor:pointer;');
1992 star3.setAttribute('src', star); 1993 star3.setAttribute('src', star);
1993 banner.appendChild(star3); 1994 banner.appendChild(star3);
1994 - 1995 +
1995 var star4 = document.createElement('img'); 1996 var star4 = document.createElement('img');
1996 star4.setAttribute('border', '0'); 1997 star4.setAttribute('border', '0');
1997 star4.setAttribute('align', 'absmiddle'); 1998 star4.setAttribute('align', 'absmiddle');
@@ -1999,16 +2000,16 @@ App.prototype.showRatingBanner = function() @@ -1999,16 +2000,16 @@ App.prototype.showRatingBanner = function()
1999 star4.setAttribute('style', 'margin-top:-6px;margin-left:3px;cursor:pointer;'); 2000 star4.setAttribute('style', 'margin-top:-6px;margin-left:3px;cursor:pointer;');
2000 star4.setAttribute('src', star); 2001 star4.setAttribute('src', star);
2001 banner.appendChild(star4); 2002 banner.appendChild(star4);
2002 - 2003 +
2003 this.bannerShowing = true; 2004 this.bannerShowing = true;
2004 - 2005 +
2005 var onclose = mxUtils.bind(this, function() 2006 var onclose = mxUtils.bind(this, function()
2006 { 2007 {
2007 if (banner.parentNode != null) 2008 if (banner.parentNode != null)
2008 { 2009 {
2009 banner.parentNode.removeChild(banner); 2010 banner.parentNode.removeChild(banner);
2010 this.bannerShowing = false; 2011 this.bannerShowing = false;
2011 - 2012 +
2012 this['hideBanner' + 'ratingFooter'] = true; 2013 this['hideBanner' + 'ratingFooter'] = true;
2013 2014
2014 if (isLocalStorage && mxSettings.settings != null) 2015 if (isLocalStorage && mxSettings.settings != null)
@@ -2018,7 +2019,7 @@ App.prototype.showRatingBanner = function() @@ -2018,7 +2019,7 @@ App.prototype.showRatingBanner = function()
2018 } 2019 }
2019 } 2020 }
2020 }); 2021 });
2021 - 2022 +
2022 mxEvent.addListener(img, 'click', mxUtils.bind(this, function(e) 2023 mxEvent.addListener(img, 'click', mxUtils.bind(this, function(e)
2023 { 2024 {
2024 mxEvent.consume(e); 2025 mxEvent.consume(e);
@@ -2049,32 +2050,32 @@ App.prototype.showRatingBanner = function() @@ -2049,32 +2050,32 @@ App.prototype.showRatingBanner = function()
2049 var hide = mxUtils.bind(this, function() 2050 var hide = mxUtils.bind(this, function()
2050 { 2051 {
2051 mxUtils.setPrefixedStyle(banner.style, 'transform', 'translate(-50%,120%)'); 2052 mxUtils.setPrefixedStyle(banner.style, 'transform', 'translate(-50%,120%)');
2052 - 2053 +
2053 window.setTimeout(mxUtils.bind(this, function() 2054 window.setTimeout(mxUtils.bind(this, function()
2054 { 2055 {
2055 onclose(); 2056 onclose();
2056 }), 1000); 2057 }), 1000);
2057 }); 2058 });
2058 - 2059 +
2059 window.setTimeout(mxUtils.bind(this, function() 2060 window.setTimeout(mxUtils.bind(this, function()
2060 { 2061 {
2061 mxUtils.setPrefixedStyle(banner.style, 'transform', 'translate(-50%,0%)'); 2062 mxUtils.setPrefixedStyle(banner.style, 'transform', 'translate(-50%,0%)');
2062 }), 500); 2063 }), 500);
2063 - 2064 +
2064 window.setTimeout(hide, 60000); 2065 window.setTimeout(hide, 60000);
2065 } 2066 }
2066 }; 2067 };
2067 2068
2068 /** 2069 /**
2069 * Checks license in the case of Google Drive storage. 2070 * Checks license in the case of Google Drive storage.
2070 - * IMPORTANT: Do not change this function without consulting 2071 + * IMPORTANT: Do not change this function without consulting
2071 * the privacy lead. No personal information must be sent. 2072 * the privacy lead. No personal information must be sent.
2072 */ 2073 */
2073 App.prototype.checkLicense = function() 2074 App.prototype.checkLicense = function()
2074 { 2075 {
2075 var driveUser = this.drive.getUser(); 2076 var driveUser = this.drive.getUser();
2076 var email = (driveUser != null) ? driveUser.email : null; 2077 var email = (driveUser != null) ? driveUser.email : null;
2077 - 2078 +
2078 if (!this.isOffline() && !this.editor.chromeless && email != null && driveUser.id != null) 2079 if (!this.isOffline() && !this.editor.chromeless && email != null && driveUser.id != null)
2079 { 2080 {
2080 // Only the domain and hashed user ID are transmitted. This code was reviewed and deemed 2081 // Only the domain and hashed user ID are transmitted. This code was reviewed and deemed
@@ -2082,9 +2083,9 @@ App.prototype.checkLicense = function() @@ -2082,9 +2083,9 @@ App.prototype.checkLicense = function()
2082 var at = email.lastIndexOf('@'); 2083 var at = email.lastIndexOf('@');
2083 var domain = (at >= 0) ? email.substring(at + 1) : ''; 2084 var domain = (at >= 0) ? email.substring(at + 1) : '';
2084 var userId = Editor.crc32(driveUser.id); 2085 var userId = Editor.crc32(driveUser.id);
2085 - 2086 +
2086 // Timestamp is workaround for cached response in certain environments 2087 // Timestamp is workaround for cached response in certain environments
2087 - mxUtils.post('/license', 'domain=' + encodeURIComponent(domain) + '&id=' + encodeURIComponent(userId) + 2088 + mxUtils.post('/license', 'domain=' + encodeURIComponent(domain) + '&id=' + encodeURIComponent(userId) +
2088 '&ts=' + new Date().getTime(), 2089 '&ts=' + new Date().getTime(),
2089 mxUtils.bind(this, function(req) 2090 mxUtils.bind(this, function(req)
2090 { 2091 {
@@ -2093,11 +2094,11 @@ App.prototype.checkLicense = function() @@ -2093,11 +2094,11 @@ App.prototype.checkLicense = function()
2093 if (req.getStatus() >= 200 && req.getStatus() <= 299) 2094 if (req.getStatus() >= 200 && req.getStatus() <= 299)
2094 { 2095 {
2095 var value = req.getText(); 2096 var value = req.getText();
2096 - 2097 +
2097 if (value.length > 0) 2098 if (value.length > 0)
2098 { 2099 {
2099 var lic = JSON.parse(value); 2100 var lic = JSON.parse(value);
2100 - 2101 +
2101 if (lic != null) 2102 if (lic != null)
2102 { 2103 {
2103 this.handleLicense(lic, domain); 2104 this.handleLicense(lic, domain);
@@ -2125,12 +2126,12 @@ App.prototype.handleLicense = function(lic, domain) @@ -2125,12 +2126,12 @@ App.prototype.handleLicense = function(lic, domain)
2125 }; 2126 };
2126 2127
2127 /** 2128 /**
2128 - * 2129 + *
2129 */ 2130 */
2130 App.prototype.getEditBlankXml = function() 2131 App.prototype.getEditBlankXml = function()
2131 { 2132 {
2132 var file = this.getCurrentFile(); 2133 var file = this.getCurrentFile();
2133 - 2134 +
2134 if (file != null && this.editor.isChromelessView() && this.editor.graph.isLightboxView()) 2135 if (file != null && this.editor.isChromelessView() && this.editor.graph.isLightboxView())
2135 { 2136 {
2136 return file.getData(); 2137 return file.getData();
@@ -2159,7 +2160,7 @@ App.prototype.addRecent = function(entry) @@ -2159,7 +2160,7 @@ App.prototype.addRecent = function(entry)
2159 if (isLocalStorage && localStorage != null) 2160 if (isLocalStorage && localStorage != null)
2160 { 2161 {
2161 var recent = this.getRecent(); 2162 var recent = this.getRecent();
2162 - 2163 +
2163 if (recent == null) 2164 if (recent == null)
2164 { 2165 {
2165 recent = []; 2166 recent = [];
@@ -2174,7 +2175,7 @@ App.prototype.addRecent = function(entry) @@ -2174,7 +2175,7 @@ App.prototype.addRecent = function(entry)
2174 } 2175 }
2175 } 2176 }
2176 } 2177 }
2177 - 2178 +
2178 if (recent != null) 2179 if (recent != null)
2179 { 2180 {
2180 recent.unshift(entry); 2181 recent.unshift(entry);
@@ -2194,7 +2195,7 @@ App.prototype.getRecent = function() @@ -2194,7 +2195,7 @@ App.prototype.getRecent = function()
2194 try 2195 try
2195 { 2196 {
2196 var recent = localStorage.getItem('.recent'); 2197 var recent = localStorage.getItem('.recent');
2197 - 2198 +
2198 if (recent != null) 2199 if (recent != null)
2199 { 2200 {
2200 return JSON.parse(recent); 2201 return JSON.parse(recent);
@@ -2204,7 +2205,7 @@ App.prototype.getRecent = function() @@ -2204,7 +2205,7 @@ App.prototype.getRecent = function()
2204 { 2205 {
2205 // ignore 2206 // ignore
2206 } 2207 }
2207 - 2208 +
2208 return null; 2209 return null;
2209 } 2210 }
2210 }; 2211 };
@@ -2239,7 +2240,7 @@ App.prototype.onBeforeUnload = function() @@ -2239,7 +2240,7 @@ App.prototype.onBeforeUnload = function()
2239 else 2240 else
2240 { 2241 {
2241 var file = this.getCurrentFile(); 2242 var file = this.getCurrentFile();
2242 - 2243 +
2243 if (file != null) 2244 if (file != null)
2244 { 2245 {
2245 // KNOWN: Message is ignored by most browsers 2246 // KNOWN: Message is ignored by most browsers
@@ -2263,7 +2264,7 @@ App.prototype.onBeforeUnload = function() @@ -2263,7 +2264,7 @@ App.prototype.onBeforeUnload = function()
2263 2264
2264 /** 2265 /**
2265 * Translates this point by the given vector. 2266 * Translates this point by the given vector.
2266 - * 2267 + *
2267 * @param {number} dx X-coordinate of the translation. 2268 * @param {number} dx X-coordinate of the translation.
2268 * @param {number} dy Y-coordinate of the translation. 2269 * @param {number} dy Y-coordinate of the translation.
2269 */ 2270 */
@@ -2273,18 +2274,18 @@ App.prototype.updateDocumentTitle = function() @@ -2273,18 +2274,18 @@ App.prototype.updateDocumentTitle = function()
2273 { 2274 {
2274 var title = this.editor.appName; 2275 var title = this.editor.appName;
2275 var file = this.getCurrentFile(); 2276 var file = this.getCurrentFile();
2276 - 2277 +
2277 if (this.isOfflineApp()) 2278 if (this.isOfflineApp())
2278 { 2279 {
2279 title += ' app'; 2280 title += ' app';
2280 } 2281 }
2281 - 2282 +
2282 if (file != null) 2283 if (file != null)
2283 { 2284 {
2284 var filename = (file.getTitle() != null) ? file.getTitle() : this.defaultFilename; 2285 var filename = (file.getTitle() != null) ? file.getTitle() : this.defaultFilename;
2285 title = filename + ' - ' + title; 2286 title = filename + ' - ' + title;
2286 } 2287 }
2287 - 2288 +
2288 if (document.title != title) 2289 if (document.title != title)
2289 { 2290 {
2290 document.title = title; 2291 document.title = title;
@@ -2301,32 +2302,32 @@ App.prototype.updateDocumentTitle = function() @@ -2301,32 +2302,32 @@ App.prototype.updateDocumentTitle = function()
2301 App.prototype.getThumbnail = function(width, fn) 2302 App.prototype.getThumbnail = function(width, fn)
2302 { 2303 {
2303 var result = false; 2304 var result = false;
2304 - 2305 +
2305 try 2306 try
2306 { 2307 {
2307 var acceptResponse = true; 2308 var acceptResponse = true;
2308 - 2309 +
2309 var timeoutThread = window.setTimeout(mxUtils.bind(this, function() 2310 var timeoutThread = window.setTimeout(mxUtils.bind(this, function()
2310 { 2311 {
2311 acceptResponse = false; 2312 acceptResponse = false;
2312 fn(null); 2313 fn(null);
2313 }), this.timeout); 2314 }), this.timeout);
2314 - 2315 +
2315 var success = mxUtils.bind(this, function(canvas) 2316 var success = mxUtils.bind(this, function(canvas)
2316 { 2317 {
2317 window.clearTimeout(timeoutThread); 2318 window.clearTimeout(timeoutThread);
2318 - 2319 +
2319 if (acceptResponse) 2320 if (acceptResponse)
2320 { 2321 {
2321 fn(canvas); 2322 fn(canvas);
2322 } 2323 }
2323 }); 2324 });
2324 - 2325 +
2325 if (this.thumbImageCache == null) 2326 if (this.thumbImageCache == null)
2326 { 2327 {
2327 this.thumbImageCache = new Object(); 2328 this.thumbImageCache = new Object();
2328 } 2329 }
2329 - 2330 +
2330 var graph = this.editor.graph; 2331 var graph = this.editor.graph;
2331 var bgImg = graph.backgroundImage; 2332 var bgImg = graph.backgroundImage;
2332 2333
@@ -2362,15 +2363,15 @@ App.prototype.getThumbnail = function(width, fn) @@ -2362,15 +2363,15 @@ App.prototype.getThumbnail = function(width, fn)
2362 { 2363 {
2363 return 1; 2364 return 1;
2364 } 2365 }
2365 - 2366 +
2366 return graphGetGlobalVariable.apply(this, arguments); 2367 return graphGetGlobalVariable.apply(this, arguments);
2367 }; 2368 };
2368 - 2369 +
2369 graph.getGlobalVariable = graphGetGlobalVariable; 2370 graph.getGlobalVariable = graphGetGlobalVariable;
2370 document.body.appendChild(graph.container); 2371 document.body.appendChild(graph.container);
2371 graph.model.setRoot(page.root); 2372 graph.model.setRoot(page.root);
2372 } 2373 }
2373 - 2374 +
2374 // Uses client-side canvas export 2375 // Uses client-side canvas export
2375 if (mxClient.IS_CHROMEAPP || this.useCanvasForExport) 2376 if (mxClient.IS_CHROMEAPP || this.useCanvasForExport)
2376 { 2377 {
@@ -2388,7 +2389,7 @@ App.prototype.getThumbnail = function(width, fn) @@ -2388,7 +2389,7 @@ App.prototype.getThumbnail = function(width, fn)
2388 { 2389 {
2389 canvas = null; 2390 canvas = null;
2390 } 2391 }
2391 - 2392 +
2392 success(canvas); 2393 success(canvas);
2393 }), width, this.thumbImageCache, '#ffffff', function() 2394 }), width, this.thumbImageCache, '#ffffff', function()
2394 { 2395 {
@@ -2396,7 +2397,7 @@ App.prototype.getThumbnail = function(width, fn) @@ -2396,7 +2397,7 @@ App.prototype.getThumbnail = function(width, fn)
2396 success(); 2397 success();
2397 }, null, null, null, null, null, null, graph, null, null, null, 2398 }, null, null, null, null, null, null, graph, null, null, null,
2398 null, 'diagram', null); 2399 null, 'diagram', null);
2399 - 2400 +
2400 result = true; 2401 result = true;
2401 } 2402 }
2402 else if (this.canvasSupported && this.getCurrentFile() != null) 2403 else if (this.canvasSupported && this.getCurrentFile() != null)
@@ -2418,33 +2419,33 @@ App.prototype.getThumbnail = function(width, fn) @@ -2418,33 +2419,33 @@ App.prototype.getThumbnail = function(width, fn)
2418 2419
2419 // Limits scale to 1 or 2 * width / height 2420 // Limits scale to 1 or 2 * width / height
2420 scale = Math.min(1, Math.min((width * 3) / (bounds.height * 4), scale)); 2421 scale = Math.min(1, Math.min((width * 3) / (bounds.height * 4), scale));
2421 - 2422 +
2422 var x0 = Math.floor(bounds.x); 2423 var x0 = Math.floor(bounds.x);
2423 var y0 = Math.floor(bounds.y); 2424 var y0 = Math.floor(bounds.y);
2424 - 2425 +
2425 canvas.setAttribute('width', Math.ceil(scale * (bounds.width + 4))); 2426 canvas.setAttribute('width', Math.ceil(scale * (bounds.width + 4)));
2426 canvas.setAttribute('height', Math.ceil(scale * (bounds.height + 4))); 2427 canvas.setAttribute('height', Math.ceil(scale * (bounds.height + 4)));
2427 - 2428 +
2428 var ctx = canvas.getContext('2d'); 2429 var ctx = canvas.getContext('2d');
2429 - 2430 +
2430 // Configures the canvas 2431 // Configures the canvas
2431 ctx.scale(scale, scale); 2432 ctx.scale(scale, scale);
2432 ctx.translate(-x0, -y0); 2433 ctx.translate(-x0, -y0);
2433 - 2434 +
2434 // Paint white background instead of transparent 2435 // Paint white background instead of transparent
2435 var bg = graph.background; 2436 var bg = graph.background;
2436 - 2437 +
2437 if (bg == null || bg == '' || bg == mxConstants.NONE) 2438 if (bg == null || bg == '' || bg == mxConstants.NONE)
2438 { 2439 {
2439 bg = '#ffffff'; 2440 bg = '#ffffff';
2440 } 2441 }
2441 - 2442 +
2442 // Paints background 2443 // Paints background
2443 ctx.save(); 2444 ctx.save();
2444 ctx.fillStyle = bg; 2445 ctx.fillStyle = bg;
2445 ctx.fillRect(x0, y0, Math.ceil(bounds.width + 4), Math.ceil(bounds.height + 4)); 2446 ctx.fillRect(x0, y0, Math.ceil(bounds.width + 4), Math.ceil(bounds.height + 4));
2446 ctx.restore(); 2447 ctx.restore();
2447 - 2448 +
2448 // Paints background image 2449 // Paints background image
2449 if (bgImg != null) 2450 if (bgImg != null)
2450 { 2451 {
@@ -2454,9 +2455,9 @@ App.prototype.getThumbnail = function(width, fn) @@ -2454,9 +2455,9 @@ App.prototype.getThumbnail = function(width, fn)
2454 ctx.drawImage(img, bgImg.x * scale, bgImg.y * scale, 2455 ctx.drawImage(img, bgImg.x * scale, bgImg.y * scale,
2455 bgImg.width * scale, bgImg.height * scale); 2456 bgImg.width * scale, bgImg.height * scale);
2456 } 2457 }
2457 - 2458 +
2458 var htmlCanvas = new mxJsCanvas(canvas); 2459 var htmlCanvas = new mxJsCanvas(canvas);
2459 - 2460 +
2460 // NOTE: htmlCanvas passed into async canvas is only used for image 2461 // NOTE: htmlCanvas passed into async canvas is only used for image
2461 // and canvas caching (canvas caching not used in this case as we do 2462 // and canvas caching (canvas caching not used in this case as we do
2462 // not render text). To reuse that cache via the thumbImageCache we 2463 // not render text). To reuse that cache via the thumbImageCache we
@@ -2465,7 +2466,7 @@ App.prototype.getThumbnail = function(width, fn) @@ -2465,7 +2466,7 @@ App.prototype.getThumbnail = function(width, fn)
2465 // LATER: Is clear thumbImageCache needed if file changes? 2466 // LATER: Is clear thumbImageCache needed if file changes?
2466 var asynCanvas = new mxAsyncCanvas(this.thumbImageCache); 2467 var asynCanvas = new mxAsyncCanvas(this.thumbImageCache);
2467 htmlCanvas.images = this.thumbImageCache.images; 2468 htmlCanvas.images = this.thumbImageCache.images;
2468 - 2469 +
2469 // Render graph 2470 // Render graph
2470 var imgExport = new mxImageExport(); 2471 var imgExport = new mxImageExport();
2471 2472
@@ -2480,20 +2481,20 @@ App.prototype.getThumbnail = function(width, fn) @@ -2480,20 +2481,20 @@ App.prototype.getThumbnail = function(width, fn)
2480 canvas.restore(); 2481 canvas.restore();
2481 } 2482 }
2482 }; 2483 };
2483 - 2484 +
2484 imgExport.drawText = function(state, canvas) 2485 imgExport.drawText = function(state, canvas)
2485 { 2486 {
2486 // No text output for thumbnails 2487 // No text output for thumbnails
2487 }; 2488 };
2488 - 2489 +
2489 imgExport.drawState(graph.getView().getState(graph.model.root), asynCanvas); 2490 imgExport.drawState(graph.getView().getState(graph.model.root), asynCanvas);
2490 - 2491 +
2491 asynCanvas.finish(mxUtils.bind(this, function() 2492 asynCanvas.finish(mxUtils.bind(this, function()
2492 { 2493 {
2493 try 2494 try
2494 { 2495 {
2495 imgExport.drawState(graph.getView().getState(graph.model.root), htmlCanvas); 2496 imgExport.drawState(graph.getView().getState(graph.model.root), htmlCanvas);
2496 - 2497 +
2497 // Removes temporary graph from DOM 2498 // Removes temporary graph from DOM
2498 if (graph != this.editor.graph && graph.container.parentNode != null) 2499 if (graph != this.editor.graph && graph.container.parentNode != null)
2499 { 2500 {
@@ -2507,32 +2508,32 @@ App.prototype.getThumbnail = function(width, fn) @@ -2507,32 +2508,32 @@ App.prototype.getThumbnail = function(width, fn)
2507 2508
2508 success(canvas); 2509 success(canvas);
2509 })); 2510 }));
2510 - 2511 +
2511 result = true; 2512 result = true;
2512 } 2513 }
2513 } 2514 }
2514 catch (e) 2515 catch (e)
2515 { 2516 {
2516 result = false; 2517 result = false;
2517 - 2518 +
2518 // Removes temporary graph from DOM 2519 // Removes temporary graph from DOM
2519 if (graph != null && graph != this.editor.graph && graph.container.parentNode != null) 2520 if (graph != null && graph != this.editor.graph && graph.container.parentNode != null)
2520 { 2521 {
2521 graph.container.parentNode.removeChild(graph.container); 2522 graph.container.parentNode.removeChild(graph.container);
2522 } 2523 }
2523 } 2524 }
2524 - 2525 +
2525 if (!result) 2526 if (!result)
2526 { 2527 {
2527 window.clearTimeout(timeoutThread); 2528 window.clearTimeout(timeoutThread);
2528 } 2529 }
2529 - 2530 +
2530 return result; 2531 return result;
2531 }; 2532 };
2532 2533
2533 /** 2534 /**
2534 * Translates this point by the given vector. 2535 * Translates this point by the given vector.
2535 - * 2536 + *
2536 * @param {number} dx X-coordinate of the translation. 2537 * @param {number} dx X-coordinate of the translation.
2537 * @param {number} dy Y-coordinate of the translation. 2538 * @param {number} dy Y-coordinate of the translation.
2538 */ 2539 */
@@ -2545,26 +2546,26 @@ App.prototype.createBackground = function() @@ -2545,26 +2546,26 @@ App.prototype.createBackground = function()
2545 bg.style.top = '0px'; 2546 bg.style.top = '0px';
2546 bg.style.bottom = '0px'; 2547 bg.style.bottom = '0px';
2547 bg.style.right = '0px'; 2548 bg.style.right = '0px';
2548 - 2549 +
2549 mxUtils.setOpacity(bg, 100); 2550 mxUtils.setOpacity(bg, 100);
2550 - 2551 +
2551 return bg; 2552 return bg;
2552 }; 2553 };
2553 2554
2554 /** 2555 /**
2555 * Translates this point by the given vector. 2556 * Translates this point by the given vector.
2556 - * 2557 + *
2557 * @param {number} dx X-coordinate of the translation. 2558 * @param {number} dx X-coordinate of the translation.
2558 * @param {number} dy Y-coordinate of the translation. 2559 * @param {number} dy Y-coordinate of the translation.
2559 */ 2560 */
2560 (function() 2561 (function()
2561 { 2562 {
2562 var editorUiSetMode = EditorUi.prototype.setMode; 2563 var editorUiSetMode = EditorUi.prototype.setMode;
2563 - 2564 +
2564 App.prototype.setMode = function(mode, remember) 2565 App.prototype.setMode = function(mode, remember)
2565 { 2566 {
2566 editorUiSetMode.apply(this, arguments); 2567 editorUiSetMode.apply(this, arguments);
2567 - 2568 +
2568 // Note: UseLocalStorage affects the file dialogs 2569 // Note: UseLocalStorage affects the file dialogs
2569 // and should not be modified if mode is undefined 2570 // and should not be modified if mode is undefined
2570 if (this.mode != null) 2571 if (this.mode != null)
@@ -2576,7 +2577,7 @@ App.prototype.createBackground = function() @@ -2576,7 +2577,7 @@ App.prototype.createBackground = function()
2576 { 2577 {
2577 var file = this.getCurrentFile(); 2578 var file = this.getCurrentFile();
2578 mode = (file != null) ? file.getMode() : mode; 2579 mode = (file != null) ? file.getMode() : mode;
2579 - 2580 +
2580 if (mode == App.MODE_GOOGLE) 2581 if (mode == App.MODE_GOOGLE)
2581 { 2582 {
2582 this.appIcon.setAttribute('title', mxResources.get('openIt', [mxResources.get('googleDrive')])); 2583 this.appIcon.setAttribute('title', mxResources.get('openIt', [mxResources.get('googleDrive')]));
@@ -2598,7 +2599,7 @@ App.prototype.createBackground = function() @@ -2598,7 +2599,7 @@ App.prototype.createBackground = function()
2598 this.appIcon.style.cursor = (mode == App.MODE_DEVICE) ? 'pointer' : 'default'; 2599 this.appIcon.style.cursor = (mode == App.MODE_DEVICE) ? 'pointer' : 'default';
2599 } 2600 }
2600 } 2601 }
2601 - 2602 +
2602 if (remember) 2603 if (remember)
2603 { 2604 {
2604 try 2605 try
@@ -2624,7 +2625,7 @@ App.prototype.createBackground = function() @@ -2624,7 +2625,7 @@ App.prototype.createBackground = function()
2624 2625
2625 /** 2626 /**
2626 * Function: authorize 2627 * Function: authorize
2627 - * 2628 + *
2628 * Authorizes the client, gets the userId and calls <open>. 2629 * Authorizes the client, gets the userId and calls <open>.
2629 */ 2630 */
2630 App.prototype.appIconClicked = function(evt) 2631 App.prototype.appIconClicked = function(evt)
@@ -2637,7 +2638,7 @@ App.prototype.appIconClicked = function(evt) @@ -2637,7 +2638,7 @@ App.prototype.appIconClicked = function(evt)
2637 { 2638 {
2638 var file = this.getCurrentFile(); 2639 var file = this.getCurrentFile();
2639 var mode = (file != null) ? file.getMode() : null; 2640 var mode = (file != null) ? file.getMode() : null;
2640 - 2641 +
2641 if (mode == App.MODE_GOOGLE) 2642 if (mode == App.MODE_GOOGLE)
2642 { 2643 {
2643 if (file != null && file.desc != null && file.desc.parents != null && 2644 if (file != null && file.desc != null && file.desc.parents != null &&
@@ -2661,12 +2662,12 @@ App.prototype.appIconClicked = function(evt) @@ -2661,12 +2662,12 @@ App.prototype.appIconClicked = function(evt)
2661 { 2662 {
2662 var url = file.meta.webUrl; 2663 var url = file.meta.webUrl;
2663 var name = encodeURIComponent(file.meta.name); 2664 var name = encodeURIComponent(file.meta.name);
2664 - 2665 +
2665 if (url.substring(url.length - name.length, url.length) == name) 2666 if (url.substring(url.length - name.length, url.length) == name)
2666 { 2667 {
2667 url = url.substring(0, url.length - name.length); 2668 url = url.substring(0, url.length - name.length);
2668 } 2669 }
2669 - 2670 +
2670 this.openLink(url); 2671 this.openLink(url);
2671 } 2672 }
2672 else 2673 else
@@ -2679,12 +2680,12 @@ App.prototype.appIconClicked = function(evt) @@ -2679,12 +2680,12 @@ App.prototype.appIconClicked = function(evt)
2679 if (file != null && file.stat != null && file.stat.path_display != null) 2680 if (file != null && file.stat != null && file.stat.path_display != null)
2680 { 2681 {
2681 var url = 'https://www.dropbox.com/home/Apps/drawio' + file.stat.path_display; 2682 var url = 'https://www.dropbox.com/home/Apps/drawio' + file.stat.path_display;
2682 - 2683 +
2683 if (!mxEvent.isShiftDown(evt)) 2684 if (!mxEvent.isShiftDown(evt))
2684 { 2685 {
2685 url = url.substring(0, url.length - file.stat.name.length); 2686 url = url.substring(0, url.length - file.stat.name.length);
2686 } 2687 }
2687 - 2688 +
2688 this.openLink(url); 2689 this.openLink(url);
2689 } 2690 }
2690 else 2691 else
@@ -2723,13 +2724,13 @@ App.prototype.appIconClicked = function(evt) @@ -2723,13 +2724,13 @@ App.prototype.appIconClicked = function(evt)
2723 this.openLink('https://get.draw.io/'); 2724 this.openLink('https://get.draw.io/');
2724 } 2725 }
2725 } 2726 }
2726 - 2727 +
2727 mxEvent.consume(evt); 2728 mxEvent.consume(evt);
2728 }; 2729 };
2729 2730
2730 /** 2731 /**
2731 * Function: authorize 2732 * Function: authorize
2732 - * 2733 + *
2733 * Authorizes the client, gets the userId and calls <open>. 2734 * Authorizes the client, gets the userId and calls <open>.
2734 */ 2735 */
2735 App.prototype.clearMode = function() 2736 App.prototype.clearMode = function()
@@ -2748,31 +2749,31 @@ App.prototype.clearMode = function() @@ -2748,31 +2749,31 @@ App.prototype.clearMode = function()
2748 2749
2749 /** 2750 /**
2750 * Translates this point by the given vector. 2751 * Translates this point by the given vector.
2751 - * 2752 + *
2752 * @param {number} dx X-coordinate of the translation. 2753 * @param {number} dx X-coordinate of the translation.
2753 * @param {number} dy Y-coordinate of the translation. 2754 * @param {number} dy Y-coordinate of the translation.
2754 */ 2755 */
2755 App.prototype.getDiagramId = function() 2756 App.prototype.getDiagramId = function()
2756 { 2757 {
2757 var id = window.location.hash; 2758 var id = window.location.hash;
2758 - 2759 +
2759 // Strips the hash sign 2760 // Strips the hash sign
2760 if (id != null && id.length > 0) 2761 if (id != null && id.length > 0)
2761 { 2762 {
2762 id = id.substring(1); 2763 id = id.substring(1);
2763 } 2764 }
2764 - 2765 +
2765 // Workaround for Trello client appending data after hash 2766 // Workaround for Trello client appending data after hash
2766 if (id != null && id.length > 1 && id.charAt(0) == 'T') 2767 if (id != null && id.length > 1 && id.charAt(0) == 'T')
2767 { 2768 {
2768 var idx = id.indexOf('#'); 2769 var idx = id.indexOf('#');
2769 - 2770 +
2770 if (idx > 0) 2771 if (idx > 0)
2771 { 2772 {
2772 id = id.substring(0, idx); 2773 id = id.substring(0, idx);
2773 } 2774 }
2774 } 2775 }
2775 - 2776 +
2776 return id; 2777 return id;
2777 }; 2778 };
2778 2779
@@ -2792,12 +2793,12 @@ App.prototype.open = function() @@ -2792,12 +2793,12 @@ App.prototype.open = function()
2792 if (window.opener != null) 2793 if (window.opener != null)
2793 { 2794 {
2794 var value = urlParams['create']; 2795 var value = urlParams['create'];
2795 - 2796 +
2796 if (value != null) 2797 if (value != null)
2797 { 2798 {
2798 value = decodeURIComponent(value); 2799 value = decodeURIComponent(value);
2799 } 2800 }
2800 - 2801 +
2801 if (value != null && value.length > 0 && value.substring(0, 7) != 'http://' && 2802 if (value != null && value.length > 0 && value.substring(0, 7) != 'http://' &&
2802 value.substring(0, 8) != 'https://') 2803 value.substring(0, 8) != 'https://')
2803 { 2804 {
@@ -2809,12 +2810,12 @@ App.prototype.open = function() @@ -2809,12 +2810,12 @@ App.prototype.open = function()
2809 window.opener.openFile.setConsumer(mxUtils.bind(this, function(xml, filename, temp) 2810 window.opener.openFile.setConsumer(mxUtils.bind(this, function(xml, filename, temp)
2810 { 2811 {
2811 this.spinner.stop(); 2812 this.spinner.stop();
2812 - 2813 +
2813 if (filename == null) 2814 if (filename == null)
2814 { 2815 {
2815 var title = urlParams['title']; 2816 var title = urlParams['title'];
2816 temp = true; 2817 temp = true;
2817 - 2818 +
2818 if (title != null) 2819 if (title != null)
2819 { 2820 {
2820 filename = decodeURIComponent(title); 2821 filename = decodeURIComponent(title);
@@ -2824,15 +2825,15 @@ App.prototype.open = function() @@ -2824,15 +2825,15 @@ App.prototype.open = function()
2824 filename = this.defaultFilename; 2825 filename = this.defaultFilename;
2825 } 2826 }
2826 } 2827 }
2827 - 2828 +
2828 // Replaces PNG with XML extension 2829 // Replaces PNG with XML extension
2829 var dot = (!this.useCanvasForExport) ? filename.substring(filename.length - 4) == '.png' : -1; 2830 var dot = (!this.useCanvasForExport) ? filename.substring(filename.length - 4) == '.png' : -1;
2830 - 2831 +
2831 if (dot > 0) 2832 if (dot > 0)
2832 { 2833 {
2833 filename = filename.substring(0, filename.length - 4) + '.drawio'; 2834 filename = filename.substring(0, filename.length - 4) + '.drawio';
2834 } 2835 }
2835 - 2836 +
2836 this.fileLoaded((mxClient.IS_IOS) ? 2837 this.fileLoaded((mxClient.IS_IOS) ?
2837 new StorageFile(this, xml, filename) : 2838 new StorageFile(this, xml, filename) :
2838 new LocalFile(this, xml, filename, temp)); 2839 new LocalFile(this, xml, filename, temp));
@@ -2856,7 +2857,7 @@ App.prototype.loadGapi = function(then) @@ -2856,7 +2857,7 @@ App.prototype.loadGapi = function(then)
2856 2857
2857 /** 2858 /**
2858 * Main function. Program starts here. 2859 * Main function. Program starts here.
2859 - * 2860 + *
2860 * @param {number} dx X-coordinate of the translation. 2861 * @param {number} dx X-coordinate of the translation.
2861 * @param {number} dy Y-coordinate of the translation. 2862 * @param {number} dy Y-coordinate of the translation.
2862 */ 2863 */
@@ -2875,9 +2876,9 @@ App.prototype.load = function() @@ -2875,9 +2876,9 @@ App.prototype.load = function()
2875 { 2876 {
2876 // ignores invalid state args 2877 // ignores invalid state args
2877 } 2878 }
2878 - 2879 +
2879 this.editor.graph.setEnabled(this.getCurrentFile() != null); 2880 this.editor.graph.setEnabled(this.getCurrentFile() != null);
2880 - 2881 +
2881 // Passes the userId from the state parameter to the client 2882 // Passes the userId from the state parameter to the client
2882 if ((window.location.hash == null || window.location.hash.length == 0) && 2883 if ((window.location.hash == null || window.location.hash.length == 0) &&
2883 this.drive != null && this.stateArg != null && this.stateArg.userId != null) 2884 this.drive != null && this.stateArg != null && this.stateArg.userId != null)
@@ -2900,7 +2901,7 @@ App.prototype.load = function() @@ -2900,7 +2901,7 @@ App.prototype.load = function()
2900 { 2901 {
2901 this.mode = null; 2902 this.mode = null;
2902 } 2903 }
2903 - 2904 +
2904 this.start(); 2905 this.start();
2905 } 2906 }
2906 else 2907 else
@@ -2916,7 +2917,7 @@ App.prototype.load = function() @@ -2916,7 +2917,7 @@ App.prototype.load = function()
2916 else 2917 else
2917 { 2918 {
2918 this.restoreLibraries(); 2919 this.restoreLibraries();
2919 - 2920 +
2920 if (urlParams['gapi'] == '1') 2921 if (urlParams['gapi'] == '1')
2921 { 2922 {
2922 this.loadGapi(function() {}); 2923 this.loadGapi(function() {});
@@ -2938,17 +2939,17 @@ App.prototype.showRefreshDialog = function(title, message) @@ -2938,17 +2939,17 @@ App.prototype.showRefreshDialog = function(title, message)
2938 mxResources.get('refresh'), mxUtils.bind(this, function() 2939 mxResources.get('refresh'), mxUtils.bind(this, function()
2939 { 2940 {
2940 var file = this.getCurrentFile(); 2941 var file = this.getCurrentFile();
2941 - 2942 +
2942 if (file != null) 2943 if (file != null)
2943 { 2944 {
2944 file.setModified(false); 2945 file.setModified(false);
2945 } 2946 }
2946 - 2947 +
2947 this.spinner.spin(document.body, mxResources.get('connecting')); 2948 this.spinner.spin(document.body, mxResources.get('connecting'));
2948 this.editor.graph.setEnabled(false); 2949 this.editor.graph.setEnabled(false);
2949 window.location.reload(); 2950 window.location.reload();
2950 }), null, null, null, null, null, 340, 180); 2951 }), null, null, null, null, null, 340, 180);
2951 - 2952 +
2952 // Adds important notice to dialog 2953 // Adds important notice to dialog
2953 if (this.dialog != null && this.dialog.container != null) 2954 if (this.dialog != null && this.dialog.container != null)
2954 { 2955 {
@@ -2975,7 +2976,7 @@ App.prototype.showAlert = function(message) @@ -2975,7 +2976,7 @@ App.prototype.showAlert = function(message)
2975 { 2976 {
2976 var div = document.createElement('div'); 2977 var div = document.createElement('div');
2977 div.className = 'geAlert'; 2978 div.className = 'geAlert';
2978 - div.style.zIndex = 2e9; 2979 + div.style.zIndex = 2e9;
2979 div.style.left = '50%'; 2980 div.style.left = '50%';
2980 div.style.top = '-100%'; 2981 div.style.top = '-100%';
2981 //Limit width to 80% max with word wrapping 2982 //Limit width to 80% max with word wrapping
@@ -2984,9 +2985,9 @@ App.prototype.showAlert = function(message) @@ -2984,9 +2985,9 @@ App.prototype.showAlert = function(message)
2984 div.style.whiteSpace = 'pre-wrap'; 2985 div.style.whiteSpace = 'pre-wrap';
2985 mxUtils.setPrefixedStyle(div.style, 'transform', 'translate(-50%,0%)'); 2986 mxUtils.setPrefixedStyle(div.style, 'transform', 'translate(-50%,0%)');
2986 mxUtils.setPrefixedStyle(div.style, 'transition', 'all 1s ease'); 2987 mxUtils.setPrefixedStyle(div.style, 'transition', 'all 1s ease');
2987 - 2988 +
2988 div.innerHTML = message; 2989 div.innerHTML = message;
2989 - 2990 +
2990 var close = document.createElement('a'); 2991 var close = document.createElement('a');
2991 close.className = 'geAlertLink'; 2992 close.className = 'geAlertLink';
2992 close.style.textAlign = 'right'; 2993 close.style.textAlign = 'right';
@@ -2995,7 +2996,7 @@ App.prototype.showAlert = function(message) @@ -2995,7 +2996,7 @@ App.prototype.showAlert = function(message)
2995 close.setAttribute('title', mxResources.get('close')); 2996 close.setAttribute('title', mxResources.get('close'));
2996 close.innerHTML = mxResources.get('close'); 2997 close.innerHTML = mxResources.get('close');
2997 div.appendChild(close); 2998 div.appendChild(close);
2998 - 2999 +
2999 mxEvent.addListener(close, 'click', function(evt) 3000 mxEvent.addListener(close, 'click', function(evt)
3000 { 3001 {
3001 if (div.parentNode != null) 3002 if (div.parentNode != null)
@@ -3004,21 +3005,21 @@ App.prototype.showAlert = function(message) @@ -3004,21 +3005,21 @@ App.prototype.showAlert = function(message)
3004 mxEvent.consume(evt); 3005 mxEvent.consume(evt);
3005 } 3006 }
3006 }); 3007 });
3007 - 3008 +
3008 document.body.appendChild(div); 3009 document.body.appendChild(div);
3009 - 3010 +
3010 // Delayed to get smoother animation after DOM rendering 3011 // Delayed to get smoother animation after DOM rendering
3011 window.setTimeout(function() 3012 window.setTimeout(function()
3012 { 3013 {
3013 div.style.top = '30px'; 3014 div.style.top = '30px';
3014 }, 10); 3015 }, 10);
3015 - 3016 +
3016 // Fades out the alert after 15 secs 3017 // Fades out the alert after 15 secs
3017 window.setTimeout(function() 3018 window.setTimeout(function()
3018 { 3019 {
3019 mxUtils.setPrefixedStyle(div.style, 'transition', 'all 2s ease'); 3020 mxUtils.setPrefixedStyle(div.style, 'transition', 'all 2s ease');
3020 div.style.opacity = '0'; 3021 div.style.opacity = '0';
3021 - 3022 +
3022 window.setTimeout(function() 3023 window.setTimeout(function()
3023 { 3024 {
3024 if (div.parentNode != null) 3025 if (div.parentNode != null)
@@ -3032,7 +3033,7 @@ App.prototype.showAlert = function(message) @@ -3032,7 +3033,7 @@ App.prototype.showAlert = function(message)
3032 3033
3033 /** 3034 /**
3034 * Translates this point by the given vector. 3035 * Translates this point by the given vector.
3035 - * 3036 + *
3036 * @param {number} dx X-coordinate of the translation. 3037 * @param {number} dx X-coordinate of the translation.
3037 * @param {number} dy Y-coordinate of the translation. 3038 * @param {number} dy Y-coordinate of the translation.
3038 */ 3039 */
@@ -3042,7 +3043,7 @@ App.prototype.start = function() @@ -3042,7 +3043,7 @@ App.prototype.start = function()
3042 { 3043 {
3043 this.bg.parentNode.removeChild(this.bg); 3044 this.bg.parentNode.removeChild(this.bg);
3044 } 3045 }
3045 - 3046 +
3046 this.restoreLibraries(); 3047 this.restoreLibraries();
3047 this.spinner.stop(); 3048 this.spinner.stop();
3048 3049
@@ -3050,7 +3051,7 @@ App.prototype.start = function() @@ -3050,7 +3051,7 @@ App.prototype.start = function()
3050 { 3051 {
3051 // Handles all errors 3052 // Handles all errors
3052 var ui = this; 3053 var ui = this;
3053 - 3054 +
3054 window.onerror = function(message, url, linenumber, colno, err) 3055 window.onerror = function(message, url, linenumber, colno, err)
3055 { 3056 {
3056 // Ignores Grammarly error [1344] 3057 // Ignores Grammarly error [1344]
@@ -3062,7 +3063,7 @@ App.prototype.start = function() @@ -3062,7 +3063,7 @@ App.prototype.start = function()
3062 null, null, null, null, true); 3063 null, null, null, null, true);
3063 } 3064 }
3064 }; 3065 };
3065 - 3066 +
3066 // Listens to changes of the hash if not in embed or client mode 3067 // Listens to changes of the hash if not in embed or client mode
3067 if (urlParams['client'] != '1' && urlParams['embed'] != '1') 3068 if (urlParams['client'] != '1' && urlParams['embed'] != '1')
3068 { 3069 {
@@ -3075,7 +3076,7 @@ App.prototype.start = function() @@ -3075,7 +3076,7 @@ App.prototype.start = function()
3075 { 3076 {
3076 var file = this.getCurrentFile(); 3077 var file = this.getCurrentFile();
3077 EditorUi.debug('storage event', [evt], [file]); 3078 EditorUi.debug('storage event', [evt], [file]);
3078 - 3079 +
3079 if (file != null && evt.key == '.draft-alive-check' && evt.newValue != null && file.draftId != null) 3080 if (file != null && evt.key == '.draft-alive-check' && evt.newValue != null && file.draftId != null)
3080 { 3081 {
3081 this.draftAliveCheck = evt.newValue; 3082 this.draftAliveCheck = evt.newValue;
@@ -3095,7 +3096,7 @@ App.prototype.start = function() @@ -3095,7 +3096,7 @@ App.prototype.start = function()
3095 { 3096 {
3096 // ignore 3097 // ignore
3097 } 3098 }
3098 - 3099 +
3099 mxEvent.addListener(window, 'hashchange', mxUtils.bind(this, function(evt) 3100 mxEvent.addListener(window, 'hashchange', mxUtils.bind(this, function(evt)
3100 { 3101 {
3101 try 3102 try
@@ -3123,7 +3124,7 @@ App.prototype.start = function() @@ -3123,7 +3124,7 @@ App.prototype.start = function()
3123 } 3124 }
3124 })); 3125 }));
3125 } 3126 }
3126 - 3127 +
3127 // Descriptor for CSV import 3128 // Descriptor for CSV import
3128 if ((window.location.hash == null || window.location.hash.length <= 1) && urlParams['desc'] != null) 3129 if ((window.location.hash == null || window.location.hash.length <= 1) && urlParams['desc'] != null)
3129 { 3130 {
@@ -3162,9 +3163,9 @@ App.prototype.start = function() @@ -3162,9 +3163,9 @@ App.prototype.start = function()
3162 { 3163 {
3163 xml = Editor.extractGraphModelFromPng(xml); 3164 xml = Editor.extractGraphModelFromPng(xml);
3164 } 3165 }
3165 - 3166 +
3166 var title = urlParams['title']; 3167 var title = urlParams['title'];
3167 - 3168 +
3168 if (title != null) 3169 if (title != null)
3169 { 3170 {
3170 title = decodeURIComponent(title); 3171 title = decodeURIComponent(title);
@@ -3173,9 +3174,9 @@ App.prototype.start = function() @@ -3173,9 +3174,9 @@ App.prototype.start = function()
3173 { 3174 {
3174 title = this.defaultFilename; 3175 title = this.defaultFilename;
3175 } 3176 }
3176 - 3177 +
3177 var file = new LocalFile(this, xml, title, true); 3178 var file = new LocalFile(this, xml, title, true);
3178 - 3179 +
3179 if (window.location.hash != null && window.location.hash.substring(0, 2) == '#P') 3180 if (window.location.hash != null && window.location.hash.substring(0, 2) == '#P')
3180 { 3181 {
3181 file.getHash = function() 3182 file.getHash = function()
@@ -3183,17 +3184,17 @@ App.prototype.start = function() @@ -3183,17 +3184,17 @@ App.prototype.start = function()
3183 return window.location.hash.substring(1); 3184 return window.location.hash.substring(1);
3184 }; 3185 };
3185 } 3186 }
3186 - 3187 +
3187 this.fileLoaded(file); 3188 this.fileLoaded(file);
3188 this.getCurrentFile().setModified(!this.editor.chromeless); 3189 this.getCurrentFile().setModified(!this.editor.chromeless);
3189 }); 3190 });
3190 3191
3191 var parent = window.opener || window.parent; 3192 var parent = window.opener || window.parent;
3192 - 3193 +
3193 if (parent != window) 3194 if (parent != window)
3194 { 3195 {
3195 var value = urlParams['create']; 3196 var value = urlParams['create'];
3196 - 3197 +
3197 if (value != null) 3198 if (value != null)
3198 { 3199 {
3199 doLoadFile(parent[decodeURIComponent(value)]); 3200 doLoadFile(parent[decodeURIComponent(value)]);
@@ -3201,7 +3202,7 @@ App.prototype.start = function() @@ -3201,7 +3202,7 @@ App.prototype.start = function()
3201 else 3202 else
3202 { 3203 {
3203 value = urlParams['data']; 3204 value = urlParams['data'];
3204 - 3205 +
3205 if (value != null) 3206 if (value != null)
3206 { 3207 {
3207 doLoadFile(decodeURIComponent(value)); 3208 doLoadFile(decodeURIComponent(value));
@@ -3232,7 +3233,7 @@ App.prototype.start = function() @@ -3232,7 +3233,7 @@ App.prototype.start = function()
3232 else 3233 else
3233 { 3234 {
3234 var waiting = false; 3235 var waiting = false;
3235 - 3236 +
3236 // Checks if we're waiting for some asynchronous file to be loaded 3237 // Checks if we're waiting for some asynchronous file to be loaded
3237 // Cross-domain window access is not allowed in FF, so if we 3238 // Cross-domain window access is not allowed in FF, so if we
3238 // were opened from another domain then this will fail. 3239 // were opened from another domain then this will fail.
@@ -3244,7 +3245,7 @@ App.prototype.start = function() @@ -3244,7 +3245,7 @@ App.prototype.start = function()
3244 { 3245 {
3245 // ignore 3246 // ignore
3246 } 3247 }
3247 - 3248 +
3248 if (waiting) 3249 if (waiting)
3249 { 3250 {
3250 // Spinner is stopped in App.open 3251 // Spinner is stopped in App.open
@@ -3253,7 +3254,7 @@ App.prototype.start = function() @@ -3253,7 +3254,7 @@ App.prototype.start = function()
3253 else 3254 else
3254 { 3255 {
3255 var id = this.getDiagramId(); 3256 var id = this.getDiagramId();
3256 - 3257 +
3257 if (EditorUi.enableDrafts && urlParams['mode'] == null && 3258 if (EditorUi.enableDrafts && urlParams['mode'] == null &&
3258 this.getServiceName() == 'draw.io' && (id == null || id.length == 0) && 3259 this.getServiceName() == 'draw.io' && (id == null || id.length == 0) &&
3259 !this.editor.isChromelessView()) 3260 !this.editor.isChromelessView())
@@ -3265,7 +3266,7 @@ App.prototype.start = function() @@ -3265,7 +3266,7 @@ App.prototype.start = function()
3265 this.loadFile(id, null, null, mxUtils.bind(this, function() 3266 this.loadFile(id, null, null, mxUtils.bind(this, function()
3266 { 3267 {
3267 var temp = decodeURIComponent(urlParams['viewbox'] || ''); 3268 var temp = decodeURIComponent(urlParams['viewbox'] || '');
3268 - 3269 +
3269 if (temp != '') 3270 if (temp != '')
3270 { 3271 {
3271 try 3272 try
@@ -3293,9 +3294,9 @@ App.prototype.start = function() @@ -3293,9 +3294,9 @@ App.prototype.start = function()
3293 } 3294 }
3294 } 3295 }
3295 }); 3296 });
3296 - 3297 +
3297 var value = decodeURIComponent(urlParams['create'] || ''); 3298 var value = decodeURIComponent(urlParams['create'] || '');
3298 - 3299 +
3299 if ((window.location.hash == null || window.location.hash.length <= 1) && 3300 if ((window.location.hash == null || window.location.hash.length <= 1) &&
3300 value != null && value.length > 0 && this.spinner.spin(document.body, mxResources.get('loading'))) 3301 value != null && value.length > 0 && this.spinner.spin(document.body, mxResources.get('loading')))
3301 { 3302 {
@@ -3307,20 +3308,20 @@ App.prototype.start = function() @@ -3307,20 +3308,20 @@ App.prototype.start = function()
3307 window.location.search = this.getSearch(['create', 'title']); 3308 window.location.search = this.getSearch(['create', 'title']);
3308 }; 3309 };
3309 }); 3310 });
3310 - 3311 +
3311 var showCreateDialog = mxUtils.bind(this, function(xml) 3312 var showCreateDialog = mxUtils.bind(this, function(xml)
3312 { 3313 {
3313 this.spinner.stop(); 3314 this.spinner.stop();
3314 - 3315 +
3315 // Resets mode for dialog - local file is only for preview 3316 // Resets mode for dialog - local file is only for preview
3316 if (urlParams['splash'] != '0') 3317 if (urlParams['splash'] != '0')
3317 { 3318 {
3318 this.fileLoaded(new LocalFile(this, xml, null)); 3319 this.fileLoaded(new LocalFile(this, xml, null));
3319 - 3320 +
3320 this.editor.graph.setEnabled(false); 3321 this.editor.graph.setEnabled(false);
3321 this.mode = urlParams['mode']; 3322 this.mode = urlParams['mode'];
3322 var title = urlParams['title']; 3323 var title = urlParams['title'];
3323 - 3324 +
3324 if (title != null) 3325 if (title != null)
3325 { 3326 {
3326 title = decodeURIComponent(title); 3327 title = decodeURIComponent(title);
@@ -3329,16 +3330,16 @@ App.prototype.start = function() @@ -3329,16 +3330,16 @@ App.prototype.start = function()
3329 { 3330 {
3330 title = this.defaultFilename; 3331 title = this.defaultFilename;
3331 } 3332 }
3332 - 3333 +
3333 var serviceCount = this.getServiceCount(true); 3334 var serviceCount = this.getServiceCount(true);
3334 - 3335 +
3335 if (isLocalStorage) 3336 if (isLocalStorage)
3336 { 3337 {
3337 serviceCount++; 3338 serviceCount++;
3338 } 3339 }
3339 - 3340 +
3340 var rowLimit = (serviceCount <= 4) ? 2 : (serviceCount > 6 ? 4 : 3); 3341 var rowLimit = (serviceCount <= 4) ? 2 : (serviceCount > 6 ? 4 : 3);
3341 - 3342 +
3342 var dlg = new CreateDialog(this, title, mxUtils.bind(this, function(filename, mode) 3343 var dlg = new CreateDialog(this, title, mxUtils.bind(this, function(filename, mode)
3343 { 3344 {
3344 if (mode == null) 3345 if (mode == null)
@@ -3371,9 +3372,9 @@ App.prototype.start = function() @@ -3371,9 +3372,9 @@ App.prototype.start = function()
3371 dlg.init(); 3372 dlg.init();
3372 } 3373 }
3373 }); 3374 });
3374 - 3375 +
3375 value = decodeURIComponent(value); 3376 value = decodeURIComponent(value);
3376 - 3377 +
3377 if (value.substring(0, 7) != 'http://' && value.substring(0, 8) != 'https://') 3378 if (value.substring(0, 7) != 'http://' && value.substring(0, 8) != 'https://')
3378 { 3379 {
3379 // Cross-domain window access is not allowed in FF, so if we 3380 // Cross-domain window access is not allowed in FF, so if we
@@ -3420,7 +3421,7 @@ App.prototype.start = function() @@ -3420,7 +3421,7 @@ App.prototype.start = function()
3420 window.history.replaceState(null, null, window.location.pathname + 3421 window.history.replaceState(null, null, window.location.pathname +
3421 this.getSearch(['state'])); 3422 this.getSearch(['state']));
3422 } 3423 }
3423 - 3424 +
3424 window.location.hash = 'G' + this.stateArg.ids[0]; 3425 window.location.hash = 'G' + this.stateArg.ids[0];
3425 } 3426 }
3426 } 3427 }
@@ -3433,7 +3434,7 @@ App.prototype.start = function() @@ -3433,7 +3434,7 @@ App.prototype.start = function()
3433 window.history.replaceState(null, null, window.location.pathname + 3434 window.history.replaceState(null, null, window.location.pathname +
3434 this.getSearch(['state'])); 3435 this.getSearch(['state']));
3435 } 3436 }
3436 - 3437 +
3437 this.setMode(App.MODE_GOOGLE); 3438 this.setMode(App.MODE_GOOGLE);
3438 3439
3439 if (urlParams['splash'] == '0') 3440 if (urlParams['splash'] == '0')
@@ -3452,12 +3453,12 @@ App.prototype.start = function() @@ -3452,12 +3453,12 @@ App.prototype.start = function()
3452 // Removes open URL parameter. Hash is also updated in Init to load client. 3453 // Removes open URL parameter. Hash is also updated in Init to load client.
3453 if (urlParams['open'] != null && window.history && window.history.replaceState) 3454 if (urlParams['open'] != null && window.history && window.history.replaceState)
3454 { 3455 {
3455 - 3456 +
3456 window.history.replaceState(null, null, window.location.pathname + 3457 window.history.replaceState(null, null, window.location.pathname +
3457 this.getSearch(['open', 'sketch'])); 3458 this.getSearch(['open', 'sketch']));
3458 window.location.hash = urlParams['open']; 3459 window.location.hash = urlParams['open'];
3459 } 3460 }
3460 - 3461 +
3461 done(); 3462 done();
3462 } 3463 }
3463 } 3464 }
@@ -3479,11 +3480,11 @@ App.prototype.loadDraft = function(xml, success) @@ -3479,11 +3480,11 @@ App.prototype.loadDraft = function(xml, success)
3479 window.setTimeout(mxUtils.bind(this, function() 3480 window.setTimeout(mxUtils.bind(this, function()
3480 { 3481 {
3481 var file = this.getCurrentFile(); 3482 var file = this.getCurrentFile();
3482 - 3483 +
3483 if (file != null) 3484 if (file != null)
3484 { 3485 {
3485 file.fileChanged(); 3486 file.fileChanged();
3486 - 3487 +
3487 if (success != null) 3488 if (success != null)
3488 { 3489 {
3489 success(); 3490 success();
@@ -3512,14 +3513,14 @@ App.prototype.filterDrafts = function(filePath, guid, callback) @@ -3512,14 +3513,14 @@ App.prototype.filterDrafts = function(filePath, guid, callback)
3512 try 3513 try
3513 { 3514 {
3514 var key = items[i].key; 3515 var key = items[i].key;
3515 - 3516 +
3516 if (key != null && key.substring(0, 7) == '.draft_') 3517 if (key != null && key.substring(0, 7) == '.draft_')
3517 { 3518 {
3518 var obj = JSON.parse(items[i].data); 3519 var obj = JSON.parse(items[i].data);
3519 -  
3520 - if (obj != null && obj.type == 'draft' && obj.aliveCheck != guid && 3520 +
  3521 + if (obj != null && obj.type == 'draft' && obj.aliveCheck != guid &&
3521 ((filePath == null && obj.fileObject == null) || 3522 ((filePath == null && obj.fileObject == null) ||
3522 - (obj.fileObject != null && obj.fileObject.path == filePath))) 3523 + (obj.fileObject != null && obj.fileObject.path == filePath)))
3523 { 3524 {
3524 obj.key = key; 3525 obj.key = key;
3525 drafts.push(obj); 3526 drafts.push(obj);
@@ -3551,7 +3552,7 @@ App.prototype.checkDrafts = function() @@ -3551,7 +3552,7 @@ App.prototype.checkDrafts = function()
3551 // Triggers storage event for other windows to mark active drafts 3552 // Triggers storage event for other windows to mark active drafts
3552 var guid = Editor.guid(); 3553 var guid = Editor.guid();
3553 localStorage.setItem('.draft-alive-check', guid); 3554 localStorage.setItem('.draft-alive-check', guid);
3554 - 3555 +
3555 window.setTimeout(mxUtils.bind(this, function() 3556 window.setTimeout(mxUtils.bind(this, function()
3556 { 3557 {
3557 localStorage.removeItem('.draft-alive-check'); 3558 localStorage.removeItem('.draft-alive-check');
@@ -3568,14 +3569,14 @@ App.prototype.checkDrafts = function() @@ -3568,14 +3569,14 @@ App.prototype.checkDrafts = function()
3568 else if (drafts.length > 1) 3569 else if (drafts.length > 1)
3569 { 3570 {
3570 var ts = new Date(drafts[0].modified); 3571 var ts = new Date(drafts[0].modified);
3571 - 3572 +
3572 var dlg = new DraftDialog(this, (drafts.length > 1) ? mxResources.get('selectDraft') : 3573 var dlg = new DraftDialog(this, (drafts.length > 1) ? mxResources.get('selectDraft') :
3573 mxResources.get('draftFound', [ts.toLocaleDateString() + ' ' + ts.toLocaleTimeString()]), 3574 mxResources.get('draftFound', [ts.toLocaleDateString() + ' ' + ts.toLocaleTimeString()]),
3574 (drafts.length > 1) ? null : drafts[0].data, mxUtils.bind(this, function(index) 3575 (drafts.length > 1) ? null : drafts[0].data, mxUtils.bind(this, function(index)
3575 { 3576 {
3576 this.hideDialog(); 3577 this.hideDialog();
3577 index = (index != '') ? index : 0; 3578 index = (index != '') ? index : 0;
3578 - 3579 +
3579 this.loadDraft(drafts[index].data, mxUtils.bind(this, function() 3580 this.loadDraft(drafts[index].data, mxUtils.bind(this, function()
3580 { 3581 {
3581 this.removeDatabaseItem(drafts[index].key); 3582 this.removeDatabaseItem(drafts[index].key);
@@ -3583,12 +3584,12 @@ App.prototype.checkDrafts = function() @@ -3583,12 +3584,12 @@ App.prototype.checkDrafts = function()
3583 }), mxUtils.bind(this, function(index, success) 3584 }), mxUtils.bind(this, function(index, success)
3584 { 3585 {
3585 index = (index != '') ? index : 0; 3586 index = (index != '') ? index : 0;
3586 - 3587 +
3587 // Discard draft 3588 // Discard draft
3588 this.confirm(mxResources.get('areYouSure'), null, mxUtils.bind(this, function() 3589 this.confirm(mxResources.get('areYouSure'), null, mxUtils.bind(this, function()
3589 { 3590 {
3590 this.removeDatabaseItem(drafts[index].key); 3591 this.removeDatabaseItem(drafts[index].key);
3591 - 3592 +
3592 if (success != null) 3593 if (success != null)
3593 { 3594 {
3594 success(); 3595 success();
@@ -3627,7 +3628,7 @@ App.prototype.checkDrafts = function() @@ -3627,7 +3628,7 @@ App.prototype.checkDrafts = function()
3627 3628
3628 /** 3629 /**
3629 * Translates this point by the given vector. 3630 * Translates this point by the given vector.
3630 - * 3631 + *
3631 * @param {number} dx X-coordinate of the translation. 3632 * @param {number} dx X-coordinate of the translation.
3632 * @param {number} dy Y-coordinate of the translation. 3633 * @param {number} dy Y-coordinate of the translation.
3633 */ 3634 */
@@ -3636,15 +3637,15 @@ App.prototype.showSplash = function(force) @@ -3636,15 +3637,15 @@ App.prototype.showSplash = function(force)
3636 //Splash dialog shouldn't be shownn when running without a file menu 3637 //Splash dialog shouldn't be shownn when running without a file menu
3637 if (urlParams['noFileMenu'] == '1') 3638 if (urlParams['noFileMenu'] == '1')
3638 { 3639 {
3639 - return; 3640 + return;
3640 } 3641 }
3641 - 3642 +
3642 var serviceCount = this.getServiceCount(true); 3643 var serviceCount = this.getServiceCount(true);
3643 - 3644 +
3644 var showSecondDialog = mxUtils.bind(this, function() 3645 var showSecondDialog = mxUtils.bind(this, function()
3645 { 3646 {
3646 var dlg = new SplashDialog(this); 3647 var dlg = new SplashDialog(this);
3647 - 3648 +
3648 this.showDialog(dlg.container, 340, (mxClient.IS_CHROMEAPP || EditorUi.isElectronApp) ? 200 : 230, true, true, 3649 this.showDialog(dlg.container, 340, (mxClient.IS_CHROMEAPP || EditorUi.isElectronApp) ? 200 : 230, true, true,
3649 mxUtils.bind(this, function(cancel) 3650 mxUtils.bind(this, function(cancel)
3650 { 3651 {
@@ -3658,7 +3659,7 @@ App.prototype.showSplash = function(force) @@ -3658,7 +3659,7 @@ App.prototype.showSplash = function(force)
3658 } 3659 }
3659 }), true); 3660 }), true);
3660 }); 3661 });
3661 - 3662 +
3662 if (this.editor.isChromelessView()) 3663 if (this.editor.isChromelessView())
3663 { 3664 {
3664 this.handleError({message: mxResources.get('noFileSelected')}, 3665 this.handleError({message: mxResources.get('noFileSelected')},
@@ -3670,13 +3671,13 @@ App.prototype.showSplash = function(force) @@ -3670,13 +3671,13 @@ App.prototype.showSplash = function(force)
3670 else if (!mxClient.IS_CHROMEAPP && (this.mode == null || force)) 3671 else if (!mxClient.IS_CHROMEAPP && (this.mode == null || force))
3671 { 3672 {
3672 var rowLimit = (serviceCount == 4) ? 2 : 3; 3673 var rowLimit = (serviceCount == 4) ? 2 : 3;
3673 - 3674 +
3674 var dlg = new StorageDialog(this, mxUtils.bind(this, function() 3675 var dlg = new StorageDialog(this, mxUtils.bind(this, function()
3675 { 3676 {
3676 this.hideDialog(); 3677 this.hideDialog();
3677 showSecondDialog(); 3678 showSecondDialog();
3678 }), rowLimit); 3679 }), rowLimit);
3679 - 3680 +
3680 this.showDialog(dlg.container, (rowLimit < 3) ? 200 : 300, 3681 this.showDialog(dlg.container, (rowLimit < 3) ? 200 : 300,
3681 ((serviceCount > 3) ? 320 : 210), true, false); 3682 ((serviceCount > 3) ? 320 : 210), true, false);
3682 } 3683 }
@@ -3688,7 +3689,7 @@ App.prototype.showSplash = function(force) @@ -3688,7 +3689,7 @@ App.prototype.showSplash = function(force)
3688 3689
3689 /** 3690 /**
3690 * Translates this point by the given vector. 3691 * Translates this point by the given vector.
3691 - * 3692 + *
3692 * @param {number} dx X-coordinate of the translation. 3693 * @param {number} dx X-coordinate of the translation.
3693 * @param {number} dy Y-coordinate of the translation. 3694 * @param {number} dy Y-coordinate of the translation.
3694 */ 3695 */
@@ -3696,7 +3697,7 @@ App.prototype.addLanguageMenu = function(elt, addLabel) @@ -3696,7 +3697,7 @@ App.prototype.addLanguageMenu = function(elt, addLabel)
3696 { 3697 {
3697 var img = null; 3698 var img = null;
3698 var langMenu = this.menus.get('language'); 3699 var langMenu = this.menus.get('language');
3699 - 3700 +
3700 if (langMenu != null) 3701 if (langMenu != null)
3701 { 3702 {
3702 img = document.createElement('div'); 3703 img = document.createElement('div');
@@ -3706,7 +3707,7 @@ App.prototype.addLanguageMenu = function(elt, addLabel) @@ -3706,7 +3707,7 @@ App.prototype.addLanguageMenu = function(elt, addLabel)
3706 img.style.cursor = 'pointer'; 3707 img.style.cursor = 'pointer';
3707 img.style.bottom = '20px'; 3708 img.style.bottom = '20px';
3708 img.style.right = '20px'; 3709 img.style.right = '20px';
3709 - 3710 +
3710 if (addLabel) 3711 if (addLabel)
3711 { 3712 {
3712 img.style.direction = 'rtl'; 3713 img.style.direction = 'rtl';
@@ -3719,11 +3720,11 @@ App.prototype.addLanguageMenu = function(elt, addLabel) @@ -3719,11 +3720,11 @@ App.prototype.addLanguageMenu = function(elt, addLabel)
3719 label.style.margin = '5px 24px 0 0'; 3720 label.style.margin = '5px 24px 0 0';
3720 label.style.color = 'gray'; 3721 label.style.color = 'gray';
3721 label.style.userSelect = 'none'; 3722 label.style.userSelect = 'none';
3722 - 3723 +
3723 mxUtils.write(label, mxResources.get('language')); 3724 mxUtils.write(label, mxResources.get('language'));
3724 img.appendChild(label); 3725 img.appendChild(label);
3725 } 3726 }
3726 - 3727 +
3727 mxEvent.addListener(img, 'click', mxUtils.bind(this, function(evt) 3728 mxEvent.addListener(img, 'click', mxUtils.bind(this, function(evt)
3728 { 3729 {
3729 this.editor.graph.popupMenuHandler.hideMenu(); 3730 this.editor.graph.popupMenuHandler.hideMenu();
@@ -3732,24 +3733,24 @@ App.prototype.addLanguageMenu = function(elt, addLabel) @@ -3732,24 +3733,24 @@ App.prototype.addLanguageMenu = function(elt, addLabel)
3732 menu.smartSeparators = true; 3733 menu.smartSeparators = true;
3733 menu.showDisabled = true; 3734 menu.showDisabled = true;
3734 menu.autoExpand = true; 3735 menu.autoExpand = true;
3735 - 3736 +
3736 // Disables autoexpand and destroys menu when hidden 3737 // Disables autoexpand and destroys menu when hidden
3737 menu.hideMenu = mxUtils.bind(this, function() 3738 menu.hideMenu = mxUtils.bind(this, function()
3738 { 3739 {
3739 mxPopupMenu.prototype.hideMenu.apply(menu, arguments); 3740 mxPopupMenu.prototype.hideMenu.apply(menu, arguments);
3740 menu.destroy(); 3741 menu.destroy();
3741 }); 3742 });
3742 - 3743 +
3743 var offset = mxUtils.getOffset(img); 3744 var offset = mxUtils.getOffset(img);
3744 menu.popup(offset.x, offset.y + img.offsetHeight, null, evt); 3745 menu.popup(offset.x, offset.y + img.offsetHeight, null, evt);
3745 - 3746 +
3746 // Allows hiding by clicking on document 3747 // Allows hiding by clicking on document
3747 this.setCurrentMenu(menu); 3748 this.setCurrentMenu(menu);
3748 })); 3749 }));
3749 - 3750 +
3750 elt.appendChild(img); 3751 elt.appendChild(img);
3751 } 3752 }
3752 - 3753 +
3753 return img; 3754 return img;
3754 }; 3755 };
3755 3756
@@ -3762,13 +3763,13 @@ App.prototype.loadFileSystemEntry = function(fileHandle, success, error) @@ -3762,13 +3763,13 @@ App.prototype.loadFileSystemEntry = function(fileHandle, success, error)
3762 { 3763 {
3763 this.handleError(e); 3764 this.handleError(e);
3764 }); 3765 });
3765 - 3766 +
3766 try 3767 try
3767 { 3768 {
3768 fileHandle.getFile().then(mxUtils.bind(this, function(file) 3769 fileHandle.getFile().then(mxUtils.bind(this, function(file)
3769 { 3770 {
3770 var reader = new FileReader(); 3771 var reader = new FileReader();
3771 - 3772 +
3772 reader.onload = mxUtils.bind(this, function(e) 3773 reader.onload = mxUtils.bind(this, function(e)
3773 { 3774 {
3774 try 3775 try
@@ -3776,12 +3777,12 @@ App.prototype.loadFileSystemEntry = function(fileHandle, success, error) @@ -3776,12 +3777,12 @@ App.prototype.loadFileSystemEntry = function(fileHandle, success, error)
3776 if (success != null) 3777 if (success != null)
3777 { 3778 {
3778 var data = e.target.result; 3779 var data = e.target.result;
3779 - 3780 +
3780 if (file.type == 'image/png') 3781 if (file.type == 'image/png')
3781 { 3782 {
3782 data = this.extractGraphModelFromPng(data); 3783 data = this.extractGraphModelFromPng(data);
3783 } 3784 }
3784 - 3785 +
3785 success(new LocalFile(this, data, file.name, null, fileHandle, file)); 3786 success(new LocalFile(this, data, file.name, null, fileHandle, file));
3786 } 3787 }
3787 else 3788 else
@@ -3794,9 +3795,9 @@ App.prototype.loadFileSystemEntry = function(fileHandle, success, error) @@ -3794,9 +3795,9 @@ App.prototype.loadFileSystemEntry = function(fileHandle, success, error)
3794 error(e); 3795 error(e);
3795 } 3796 }
3796 }); 3797 });
3797 - 3798 +
3798 reader.onerror = error; 3799 reader.onerror = error;
3799 - 3800 +
3800 if ((file.type.substring(0, 5) === 'image' || 3801 if ((file.type.substring(0, 5) === 'image' ||
3801 file.type === 'application/pdf') && 3802 file.type === 'application/pdf') &&
3802 file.type.substring(0, 9) !== 'image/svg') 3803 file.type.substring(0, 9) !== 'image/svg')
@@ -3822,24 +3823,24 @@ App.prototype.createFileSystemOptions = function(name) @@ -3822,24 +3823,24 @@ App.prototype.createFileSystemOptions = function(name)
3822 { 3823 {
3823 var ext = []; 3824 var ext = [];
3824 var temp = null; 3825 var temp = null;
3825 - 3826 +
3826 if (name != null) 3827 if (name != null)
3827 { 3828 {
3828 var idx = name.lastIndexOf('.'); 3829 var idx = name.lastIndexOf('.');
3829 - 3830 +
3830 if (idx > 0) 3831 if (idx > 0)
3831 { 3832 {
3832 temp = name.substring(idx + 1); 3833 temp = name.substring(idx + 1);
3833 } 3834 }
3834 } 3835 }
3835 - 3836 +
3836 for (var i = 0; i < this.editor.diagramFileTypes.length; i++) 3837 for (var i = 0; i < this.editor.diagramFileTypes.length; i++)
3837 { 3838 {
3838 var obj = {description: mxResources.get(this.editor.diagramFileTypes[i].description) + 3839 var obj = {description: mxResources.get(this.editor.diagramFileTypes[i].description) +
3839 ((mxClient.IS_MAC) ? ' (.' + this.editor.diagramFileTypes[i].extension + ')' : ''), 3840 ((mxClient.IS_MAC) ? ' (.' + this.editor.diagramFileTypes[i].extension + ')' : ''),
3840 accept: {}}; 3841 accept: {}};
3841 obj.accept[this.editor.diagramFileTypes[i].mimeType] = ['.' + this.editor.diagramFileTypes[i].extension]; 3842 obj.accept[this.editor.diagramFileTypes[i].mimeType] = ['.' + this.editor.diagramFileTypes[i].extension];
3842 - 3843 +
3843 if (this.editor.diagramFileTypes[i].extension == temp) 3844 if (this.editor.diagramFileTypes[i].extension == temp)
3844 { 3845 {
3845 ext.splice(0, 0, obj); 3846 ext.splice(0, 0, obj);
@@ -3856,7 +3857,7 @@ App.prototype.createFileSystemOptions = function(name) @@ -3856,7 +3857,7 @@ App.prototype.createFileSystemOptions = function(name)
3856 } 3857 }
3857 } 3858 }
3858 } 3859 }
3859 - 3860 +
3860 // TODO: Specify default filename 3861 // TODO: Specify default filename
3861 return {types: ext, fileName: name}; 3862 return {types: ext, fileName: name};
3862 }; 3863 };
@@ -3873,9 +3874,9 @@ App.prototype.showSaveFilePicker = function(success, error, opts) @@ -3873,9 +3874,9 @@ App.prototype.showSaveFilePicker = function(success, error, opts)
3873 this.handleError(e); 3874 this.handleError(e);
3874 } 3875 }
3875 }); 3876 });
3876 - 3877 +
3877 opts = (opts != null) ? opts : this.createFileSystemOptions(); 3878 opts = (opts != null) ? opts : this.createFileSystemOptions();
3878 - 3879 +
3879 window.showSaveFilePicker(opts).then(mxUtils.bind(this, function(fileHandle) 3880 window.showSaveFilePicker(opts).then(mxUtils.bind(this, function(fileHandle)
3880 { 3881 {
3881 if (fileHandle != null) 3882 if (fileHandle != null)
@@ -3890,7 +3891,7 @@ App.prototype.showSaveFilePicker = function(success, error, opts) @@ -3890,7 +3891,7 @@ App.prototype.showSaveFilePicker = function(success, error, opts)
3890 3891
3891 /** 3892 /**
3892 * Translates this point by the given vector. 3893 * Translates this point by the given vector.
3893 - * 3894 + *
3894 * @param {number} dx X-coordinate of the translation. 3895 * @param {number} dx X-coordinate of the translation.
3895 * @param {number} dy Y-coordinate of the translation. 3896 * @param {number} dy Y-coordinate of the translation.
3896 */ 3897 */
@@ -3899,7 +3900,7 @@ App.prototype.pickFile = function(mode) @@ -3899,7 +3900,7 @@ App.prototype.pickFile = function(mode)
3899 try 3900 try
3900 { 3901 {
3901 mode = (mode != null) ? mode : this.mode; 3902 mode = (mode != null) ? mode : this.mode;
3902 - 3903 +
3903 if (mode == App.MODE_GOOGLE) 3904 if (mode == App.MODE_GOOGLE)
3904 { 3905 {
3905 if (this.drive != null && typeof(google) != 'undefined' && typeof(google.picker) != 'undefined') 3906 if (this.drive != null && typeof(google) != 'undefined' && typeof(google.picker) != 'undefined')
@@ -3914,7 +3915,7 @@ App.prototype.pickFile = function(mode) @@ -3914,7 +3915,7 @@ App.prototype.pickFile = function(mode)
3914 else 3915 else
3915 { 3916 {
3916 var peer = this.getPeerForMode(mode); 3917 var peer = this.getPeerForMode(mode);
3917 - 3918 +
3918 if (peer != null) 3919 if (peer != null)
3919 { 3920 {
3920 peer.pickFile(); 3921 peer.pickFile();
@@ -3938,17 +3939,17 @@ App.prototype.pickFile = function(mode) @@ -3938,17 +3939,17 @@ App.prototype.pickFile = function(mode)
3938 } 3939 }
3939 else if (mode == App.MODE_DEVICE && Graph.fileSupport) 3940 else if (mode == App.MODE_DEVICE && Graph.fileSupport)
3940 { 3941 {
3941 - if (this.openFileInputElt == null) 3942 + if (this.openFileInputElt == null)
3942 { 3943 {
3943 var input = document.createElement('input'); 3944 var input = document.createElement('input');
3944 input.setAttribute('type', 'file'); 3945 input.setAttribute('type', 'file');
3945 - 3946 +
3946 mxEvent.addListener(input, 'change', mxUtils.bind(this, function() 3947 mxEvent.addListener(input, 'change', mxUtils.bind(this, function()
3947 { 3948 {
3948 if (input.files != null) 3949 if (input.files != null)
3949 { 3950 {
3950 this.openFiles(input.files); 3951 this.openFiles(input.files);
3951 - 3952 +
3952 // Resets input to force change event for 3953 // Resets input to force change event for
3953 // same file (type reset required for IE) 3954 // same file (type reset required for IE)
3954 input.type = ''; 3955 input.type = '';
@@ -3956,12 +3957,12 @@ App.prototype.pickFile = function(mode) @@ -3956,12 +3957,12 @@ App.prototype.pickFile = function(mode)
3956 input.value = ''; 3957 input.value = '';
3957 } 3958 }
3958 })); 3959 }));
3959 - 3960 +
3960 input.style.display = 'none'; 3961 input.style.display = 'none';
3961 document.body.appendChild(input); 3962 document.body.appendChild(input);
3962 this.openFileInputElt = input; 3963 this.openFileInputElt = input;
3963 } 3964 }
3964 - 3965 +
3965 this.openFileInputElt.click(); 3966 this.openFileInputElt.click();
3966 } 3967 }
3967 else 3968 else
@@ -3970,26 +3971,26 @@ App.prototype.pickFile = function(mode) @@ -3970,26 +3971,26 @@ App.prototype.pickFile = function(mode)
3970 window.openNew = this.getCurrentFile() != null && !this.isDiagramEmpty(); 3971 window.openNew = this.getCurrentFile() != null && !this.isDiagramEmpty();
3971 window.baseUrl = this.getUrl(); 3972 window.baseUrl = this.getUrl();
3972 window.openKey = 'open'; 3973 window.openKey = 'open';
3973 -  
3974 - window.listBrowserFiles = mxUtils.bind(this, function(success, error) 3974 +
  3975 + window.listBrowserFiles = mxUtils.bind(this, function(success, error)
3975 { 3976 {
3976 StorageFile.listFiles(this, 'F', success, error); 3977 StorageFile.listFiles(this, 'F', success, error);
3977 }); 3978 });
3978 - 3979 +
3979 window.openBrowserFile = mxUtils.bind(this, function(title, success, error) 3980 window.openBrowserFile = mxUtils.bind(this, function(title, success, error)
3980 { 3981 {
3981 StorageFile.getFileContent(this, title, success, error); 3982 StorageFile.getFileContent(this, title, success, error);
3982 }); 3983 });
3983 - 3984 +
3984 window.deleteBrowserFile = mxUtils.bind(this, function(title, success, error) 3985 window.deleteBrowserFile = mxUtils.bind(this, function(title, success, error)
3985 { 3986 {
3986 StorageFile.deleteFile(this, title, success, error); 3987 StorageFile.deleteFile(this, title, success, error);
3987 }); 3988 });
3988 - 3989 +
3989 var prevValue = Editor.useLocalStorage; 3990 var prevValue = Editor.useLocalStorage;
3990 Editor.useLocalStorage = (mode == App.MODE_BROWSER); 3991 Editor.useLocalStorage = (mode == App.MODE_BROWSER);
3991 this.openFile(); 3992 this.openFile();
3992 - 3993 +
3993 // Installs local handler for opened files in same window 3994 // Installs local handler for opened files in same window
3994 window.openFile.setConsumer(mxUtils.bind(this, function(xml, filename) 3995 window.openFile.setConsumer(mxUtils.bind(this, function(xml, filename)
3995 { 3996 {
@@ -3997,19 +3998,19 @@ App.prototype.pickFile = function(mode) @@ -3997,19 +3998,19 @@ App.prototype.pickFile = function(mode)
3997 { 3998 {
3998 // Replaces PNG with XML extension 3999 // Replaces PNG with XML extension
3999 var dot = !this.useCanvasForExport && filename.substring(filename.length - 4) == '.png'; 4000 var dot = !this.useCanvasForExport && filename.substring(filename.length - 4) == '.png';
4000 - 4001 +
4001 if (dot) 4002 if (dot)
4002 { 4003 {
4003 filename = filename.substring(0, filename.length - 4) + '.drawio'; 4004 filename = filename.substring(0, filename.length - 4) + '.drawio';
4004 } 4005 }
4005 - 4006 +
4006 this.fileLoaded((mode == App.MODE_BROWSER) ? 4007 this.fileLoaded((mode == App.MODE_BROWSER) ?
4007 new StorageFile(this, xml, filename) : 4008 new StorageFile(this, xml, filename) :
4008 new LocalFile(this, xml, filename)); 4009 new LocalFile(this, xml, filename));
4009 }); 4010 });
4010 - 4011 +
4011 var currentFile = this.getCurrentFile(); 4012 var currentFile = this.getCurrentFile();
4012 - 4013 +
4013 if (currentFile == null || !currentFile.isModified()) 4014 if (currentFile == null || !currentFile.isModified())
4014 { 4015 {
4015 doOpenFile(); 4016 doOpenFile();
@@ -4020,16 +4021,16 @@ App.prototype.pickFile = function(mode) @@ -4020,16 +4021,16 @@ App.prototype.pickFile = function(mode)
4020 mxResources.get('cancel'), mxResources.get('discardChanges')); 4021 mxResources.get('cancel'), mxResources.get('discardChanges'));
4021 } 4022 }
4022 })); 4023 }));
4023 - 4024 +
4024 // Extends dialog close to show splash screen 4025 // Extends dialog close to show splash screen
4025 var dlg = this.dialog; 4026 var dlg = this.dialog;
4026 var dlgClose = dlg.close; 4027 var dlgClose = dlg.close;
4027 - 4028 +
4028 this.dialog.close = mxUtils.bind(this, function(cancel) 4029 this.dialog.close = mxUtils.bind(this, function(cancel)
4029 { 4030 {
4030 Editor.useLocalStorage = prevValue; 4031 Editor.useLocalStorage = prevValue;
4031 dlgClose.apply(dlg, arguments); 4032 dlgClose.apply(dlg, arguments);
4032 - 4033 +
4033 if (this.getCurrentFile() == null) 4034 if (this.getCurrentFile() == null)
4034 { 4035 {
4035 this.showSplash(); 4036 this.showSplash();
@@ -4046,14 +4047,14 @@ App.prototype.pickFile = function(mode) @@ -4046,14 +4047,14 @@ App.prototype.pickFile = function(mode)
4046 4047
4047 /** 4048 /**
4048 * Translates this point by the given vector. 4049 * Translates this point by the given vector.
4049 - * 4050 + *
4050 * @param {number} dx X-coordinate of the translation. 4051 * @param {number} dx X-coordinate of the translation.
4051 * @param {number} dy Y-coordinate of the translation. 4052 * @param {number} dy Y-coordinate of the translation.
4052 */ 4053 */
4053 App.prototype.pickLibrary = function(mode) 4054 App.prototype.pickLibrary = function(mode)
4054 { 4055 {
4055 mode = (mode != null) ? mode : this.mode; 4056 mode = (mode != null) ? mode : this.mode;
4056 - 4057 +
4057 if (mode == App.MODE_GOOGLE || mode == App.MODE_DROPBOX || mode == App.MODE_ONEDRIVE || 4058 if (mode == App.MODE_GOOGLE || mode == App.MODE_DROPBOX || mode == App.MODE_ONEDRIVE ||
4058 mode == App.MODE_GITHUB || mode == App.MODE_GITLAB || mode == App.MODE_TRELLO) 4059 mode == App.MODE_GITHUB || mode == App.MODE_GITLAB || mode == App.MODE_TRELLO)
4059 { 4060 {
@@ -4063,7 +4064,7 @@ App.prototype.pickLibrary = function(mode) @@ -4063,7 +4064,7 @@ App.prototype.pickLibrary = function(mode)
4063 ((mode == App.MODE_GITLAB) ? this.gitLab : 4064 ((mode == App.MODE_GITLAB) ? this.gitLab :
4064 ((mode == App.MODE_TRELLO) ? this.trello : 4065 ((mode == App.MODE_TRELLO) ? this.trello :
4065 this.dropbox)))); 4066 this.dropbox))));
4066 - 4067 +
4067 if (peer != null) 4068 if (peer != null)
4068 { 4069 {
4069 peer.pickLibrary(mxUtils.bind(this, function(id, optionalFile) 4070 peer.pickLibrary(mxUtils.bind(this, function(id, optionalFile)
@@ -4086,7 +4087,7 @@ App.prototype.pickLibrary = function(mode) @@ -4086,7 +4087,7 @@ App.prototype.pickLibrary = function(mode)
4086 peer.getLibrary(id, mxUtils.bind(this, function(file) 4087 peer.getLibrary(id, mxUtils.bind(this, function(file)
4087 { 4088 {
4088 this.spinner.stop(); 4089 this.spinner.stop();
4089 - 4090 +
4090 try 4091 try
4091 { 4092 {
4092 this.loadLibrary(file); 4093 this.loadLibrary(file);
@@ -4106,11 +4107,11 @@ App.prototype.pickLibrary = function(mode) @@ -4106,11 +4107,11 @@ App.prototype.pickLibrary = function(mode)
4106 } 4107 }
4107 else if (mode == App.MODE_DEVICE && Graph.fileSupport) 4108 else if (mode == App.MODE_DEVICE && Graph.fileSupport)
4108 { 4109 {
4109 - if (this.libFileInputElt == null) 4110 + if (this.libFileInputElt == null)
4110 { 4111 {
4111 var input = document.createElement('input'); 4112 var input = document.createElement('input');
4112 input.setAttribute('type', 'file'); 4113 input.setAttribute('type', 'file');
4113 - 4114 +
4114 mxEvent.addListener(input, 'change', mxUtils.bind(this, function() 4115 mxEvent.addListener(input, 'change', mxUtils.bind(this, function()
4115 { 4116 {
4116 if (input.files != null) 4117 if (input.files != null)
@@ -4120,7 +4121,7 @@ App.prototype.pickLibrary = function(mode) @@ -4120,7 +4121,7 @@ App.prototype.pickLibrary = function(mode)
4120 (mxUtils.bind(this, function(file) 4121 (mxUtils.bind(this, function(file)
4121 { 4122 {
4122 var reader = new FileReader(); 4123 var reader = new FileReader();
4123 - 4124 +
4124 reader.onload = mxUtils.bind(this, function(e) 4125 reader.onload = mxUtils.bind(this, function(e)
4125 { 4126 {
4126 try 4127 try
@@ -4132,54 +4133,54 @@ App.prototype.pickLibrary = function(mode) @@ -4132,54 +4133,54 @@ App.prototype.pickLibrary = function(mode)
4132 this.handleError(e, mxResources.get('errorLoadingFile')); 4133 this.handleError(e, mxResources.get('errorLoadingFile'));
4133 } 4134 }
4134 }); 4135 });
4135 - 4136 +
4136 reader.readAsText(file); 4137 reader.readAsText(file);
4137 }))(input.files[i]); 4138 }))(input.files[i]);
4138 } 4139 }
4139 - 4140 +
4140 // Resets input to force change event for same file (type reset required for IE) 4141 // Resets input to force change event for same file (type reset required for IE)
4141 input.type = ''; 4142 input.type = '';
4142 input.type = 'file'; 4143 input.type = 'file';
4143 input.value = ''; 4144 input.value = '';
4144 } 4145 }
4145 })); 4146 }));
4146 - 4147 +
4147 input.style.display = 'none'; 4148 input.style.display = 'none';
4148 document.body.appendChild(input); 4149 document.body.appendChild(input);
4149 this.libFileInputElt = input; 4150 this.libFileInputElt = input;
4150 } 4151 }
4151 - 4152 +
4152 this.libFileInputElt.click(); 4153 this.libFileInputElt.click();
4153 } 4154 }
4154 else 4155 else
4155 { 4156 {
4156 window.openNew = false; 4157 window.openNew = false;
4157 window.openKey = 'open'; 4158 window.openKey = 'open';
4158 -  
4159 - window.listBrowserFiles = mxUtils.bind(this, function(success, error) 4159 +
  4160 + window.listBrowserFiles = mxUtils.bind(this, function(success, error)
4160 { 4161 {
4161 StorageFile.listFiles(this, 'L', success, error); 4162 StorageFile.listFiles(this, 'L', success, error);
4162 }); 4163 });
4163 - 4164 +
4164 window.openBrowserFile = mxUtils.bind(this, function(title, success, error) 4165 window.openBrowserFile = mxUtils.bind(this, function(title, success, error)
4165 { 4166 {
4166 StorageFile.getFileContent(this, title, success, error); 4167 StorageFile.getFileContent(this, title, success, error);
4167 }); 4168 });
4168 - 4169 +
4169 window.deleteBrowserFile = mxUtils.bind(this, function(title, success, error) 4170 window.deleteBrowserFile = mxUtils.bind(this, function(title, success, error)
4170 { 4171 {
4171 StorageFile.deleteFile(this, title, success, error); 4172 StorageFile.deleteFile(this, title, success, error);
4172 }); 4173 });
4173 - 4174 +
4174 var prevValue = Editor.useLocalStorage; 4175 var prevValue = Editor.useLocalStorage;
4175 Editor.useLocalStorage = mode == App.MODE_BROWSER; 4176 Editor.useLocalStorage = mode == App.MODE_BROWSER;
4176 - 4177 +
4177 // Closes dialog after open 4178 // Closes dialog after open
4178 window.openFile = new OpenFile(mxUtils.bind(this, function(cancel) 4179 window.openFile = new OpenFile(mxUtils.bind(this, function(cancel)
4179 { 4180 {
4180 this.hideDialog(cancel); 4181 this.hideDialog(cancel);
4181 })); 4182 }));
4182 - 4183 +
4183 window.openFile.setConsumer(mxUtils.bind(this, function(xml, filename) 4184 window.openFile.setConsumer(mxUtils.bind(this, function(xml, filename)
4184 { 4185 {
4185 try 4186 try
@@ -4205,7 +4206,7 @@ App.prototype.pickLibrary = function(mode) @@ -4205,7 +4206,7 @@ App.prototype.pickLibrary = function(mode)
4205 4206
4206 /** 4207 /**
4207 * Translates this point by the given vector. 4208 * Translates this point by the given vector.
4208 - * 4209 + *
4209 * @param {number} dx X-coordinate of the translation. 4210 * @param {number} dx X-coordinate of the translation.
4210 * @param {number} dy Y-coordinate of the translation. 4211 * @param {number} dy Y-coordinate of the translation.
4211 */ 4212 */
@@ -4217,25 +4218,25 @@ App.prototype.saveLibrary = function(name, images, file, mode, noSpin, noReload, @@ -4217,25 +4218,25 @@ App.prototype.saveLibrary = function(name, images, file, mode, noSpin, noReload,
4217 noSpin = (noSpin != null) ? noSpin : false; 4218 noSpin = (noSpin != null) ? noSpin : false;
4218 noReload = (noReload != null) ? noReload : false; 4219 noReload = (noReload != null) ? noReload : false;
4219 var xml = this.createLibraryDataFromImages(images); 4220 var xml = this.createLibraryDataFromImages(images);
4220 - 4221 +
4221 var error = mxUtils.bind(this, function(resp) 4222 var error = mxUtils.bind(this, function(resp)
4222 { 4223 {
4223 this.spinner.stop(); 4224 this.spinner.stop();
4224 - 4225 +
4225 if (fn != null) 4226 if (fn != null)
4226 { 4227 {
4227 fn(); 4228 fn();
4228 } 4229 }
4229 - 4230 +
4230 this.handleError(resp, (resp != null) ? mxResources.get('errorSavingFile') : null); 4231 this.handleError(resp, (resp != null) ? mxResources.get('errorSavingFile') : null);
4231 }); 4232 });
4232 - 4233 +
4233 // Handles special case for local libraries 4234 // Handles special case for local libraries
4234 if (file == null && mode == App.MODE_DEVICE) 4235 if (file == null && mode == App.MODE_DEVICE)
4235 { 4236 {
4236 file = new LocalLibrary(this, xml, name); 4237 file = new LocalLibrary(this, xml, name);
4237 } 4238 }
4238 - 4239 +
4239 if (file == null) 4240 if (file == null)
4240 { 4241 {
4241 this.pickFolder(mode, mxUtils.bind(this, function(folderId) 4242 this.pickFolder(mode, mxUtils.bind(this, function(folderId)
@@ -4299,7 +4300,7 @@ App.prototype.saveLibrary = function(name, images, file, mode, noSpin, noReload, @@ -4299,7 +4300,7 @@ App.prototype.saveLibrary = function(name, images, file, mode, noSpin, noReload,
4299 var fn = mxUtils.bind(this, function() 4300 var fn = mxUtils.bind(this, function()
4300 { 4301 {
4301 var file = new StorageLibrary(this, xml, name); 4302 var file = new StorageLibrary(this, xml, name);
4302 - 4303 +
4303 // Inserts data into local storage 4304 // Inserts data into local storage
4304 file.saveFile(name, false, mxUtils.bind(this, function() 4305 file.saveFile(name, false, mxUtils.bind(this, function()
4305 { 4306 {
@@ -4307,7 +4308,7 @@ App.prototype.saveLibrary = function(name, images, file, mode, noSpin, noReload, @@ -4307,7 +4308,7 @@ App.prototype.saveLibrary = function(name, images, file, mode, noSpin, noReload,
4307 this.libraryLoaded(file, images); 4308 this.libraryLoaded(file, images);
4308 }), error); 4309 }), error);
4309 }); 4310 });
4310 - 4311 +
4311 if (localStorage.getItem(name) == null) 4312 if (localStorage.getItem(name) == null)
4312 { 4313 {
4313 fn(); 4314 fn();
@@ -4326,30 +4327,30 @@ App.prototype.saveLibrary = function(name, images, file, mode, noSpin, noReload, @@ -4326,30 +4327,30 @@ App.prototype.saveLibrary = function(name, images, file, mode, noSpin, noReload,
4326 else if (noSpin || this.spinner.spin(document.body, mxResources.get('saving'))) 4327 else if (noSpin || this.spinner.spin(document.body, mxResources.get('saving')))
4327 { 4328 {
4328 file.setData(xml); 4329 file.setData(xml);
4329 - 4330 +
4330 var doSave = mxUtils.bind(this, function() 4331 var doSave = mxUtils.bind(this, function()
4331 { 4332 {
4332 file.save(true, mxUtils.bind(this, function(resp) 4333 file.save(true, mxUtils.bind(this, function(resp)
4333 { 4334 {
4334 this.spinner.stop(); 4335 this.spinner.stop();
4335 this.hideDialog(true); 4336 this.hideDialog(true);
4336 - 4337 +
4337 if (!noReload) 4338 if (!noReload)
4338 { 4339 {
4339 this.libraryLoaded(file, images); 4340 this.libraryLoaded(file, images);
4340 } 4341 }
4341 - 4342 +
4342 if (fn != null) 4343 if (fn != null)
4343 { 4344 {
4344 fn(); 4345 fn();
4345 } 4346 }
4346 }), error); 4347 }), error);
4347 }); 4348 });
4348 - 4349 +
4349 if (name != file.getTitle()) 4350 if (name != file.getTitle())
4350 { 4351 {
4351 var oldHash = file.getHash(); 4352 var oldHash = file.getHash();
4352 - 4353 +
4353 file.rename(name, mxUtils.bind(this, function(resp) 4354 file.rename(name, mxUtils.bind(this, function(resp)
4354 { 4355 {
4355 // Change hash in stored settings 4356 // Change hash in stored settings
@@ -4358,12 +4359,12 @@ App.prototype.saveLibrary = function(name, images, file, mode, noSpin, noReload, @@ -4358,12 +4359,12 @@ App.prototype.saveLibrary = function(name, images, file, mode, noSpin, noReload,
4358 mxSettings.removeCustomLibrary(oldHash); 4359 mxSettings.removeCustomLibrary(oldHash);
4359 mxSettings.addCustomLibrary(file.getHash()); 4360 mxSettings.addCustomLibrary(file.getHash());
4360 } 4361 }
4361 - 4362 +
4362 // Workaround for library files changing hash so 4363 // Workaround for library files changing hash so
4363 // the old library cannot be removed from the 4364 // the old library cannot be removed from the
4364 // sidebar using the updated file in libraryLoaded 4365 // sidebar using the updated file in libraryLoaded
4365 this.removeLibrarySidebar(oldHash); 4366 this.removeLibrarySidebar(oldHash);
4366 - 4367 +
4367 doSave(); 4368 doSave();
4368 }), error) 4369 }), error)
4369 } 4370 }
@@ -4385,7 +4386,7 @@ App.prototype.saveLibrary = function(name, images, file, mode, noSpin, noReload, @@ -4385,7 +4386,7 @@ App.prototype.saveLibrary = function(name, images, file, mode, noSpin, noReload,
4385 App.prototype.saveFile = function(forceDialog, success) 4386 App.prototype.saveFile = function(forceDialog, success)
4386 { 4387 {
4387 var file = this.getCurrentFile(); 4388 var file = this.getCurrentFile();
4388 - 4389 +
4389 if (file != null) 4390 if (file != null)
4390 { 4391 {
4391 // FIXME: Invoke for local files 4392 // FIXME: Invoke for local files
@@ -4395,7 +4396,7 @@ App.prototype.saveFile = function(forceDialog, success) @@ -4395,7 +4396,7 @@ App.prototype.saveFile = function(forceDialog, success)
4395 { 4396 {
4396 file.removeDraft(); 4397 file.removeDraft();
4397 } 4398 }
4398 - 4399 +
4399 if (this.getCurrentFile() != file && !file.isModified()) 4400 if (this.getCurrentFile() != file && !file.isModified())
4400 { 4401 {
4401 // Workaround for possible status update while save as dialog is showing 4402 // Workaround for possible status update while save as dialog is showing
@@ -4409,13 +4410,13 @@ App.prototype.saveFile = function(forceDialog, success) @@ -4409,13 +4410,13 @@ App.prototype.saveFile = function(forceDialog, success)
4409 this.editor.setStatus(''); 4410 this.editor.setStatus('');
4410 } 4411 }
4411 } 4412 }
4412 - 4413 +
4413 if (success != null) 4414 if (success != null)
4414 { 4415 {
4415 success(); 4416 success();
4416 } 4417 }
4417 }); 4418 });
4418 - 4419 +
4419 if (!forceDialog && file.getTitle() != null && file.invalidFileHandle == null && this.mode != null) 4420 if (!forceDialog && file.getTitle() != null && file.invalidFileHandle == null && this.mode != null)
4420 { 4421 {
4421 this.save(file.getTitle(), done); 4422 this.save(file.getTitle(), done);
@@ -4437,14 +4438,14 @@ App.prototype.saveFile = function(forceDialog, success) @@ -4437,14 +4438,14 @@ App.prototype.saveFile = function(forceDialog, success)
4437 var allowTab = !mxClient.IS_IOS || !navigator.standalone; 4438 var allowTab = !mxClient.IS_IOS || !navigator.standalone;
4438 var prev = this.mode; 4439 var prev = this.mode;
4439 var serviceCount = this.getServiceCount(true); 4440 var serviceCount = this.getServiceCount(true);
4440 - 4441 +
4441 if (isLocalStorage) 4442 if (isLocalStorage)
4442 { 4443 {
4443 serviceCount++; 4444 serviceCount++;
4444 } 4445 }
4445 - 4446 +
4446 var rowLimit = (serviceCount <= 4) ? 2 : (serviceCount > 6 ? 4 : 3); 4447 var rowLimit = (serviceCount <= 4) ? 2 : (serviceCount > 6 ? 4 : 3);
4447 - 4448 +
4448 var dlg = new CreateDialog(this, filename, mxUtils.bind(this, function(name, mode, input) 4449 var dlg = new CreateDialog(this, filename, mxUtils.bind(this, function(name, mode, input)
4449 { 4450 {
4450 if (name != null && name.length > 0) 4451 if (name != null && name.length > 0)
@@ -4460,7 +4461,7 @@ App.prototype.saveFile = function(forceDialog, success) @@ -4460,7 +4461,7 @@ App.prototype.saveFile = function(forceDialog, success)
4460 { 4461 {
4461 input.value = name.split('.').slice(0, -1).join('.'); 4462 input.value = name.split('.').slice(0, -1).join('.');
4462 input.focus(); 4463 input.focus();
4463 - 4464 +
4464 if (mxClient.IS_GC || mxClient.IS_FF || document.documentMode >= 5) 4465 if (mxClient.IS_GC || mxClient.IS_FF || document.documentMode >= 5)
4465 { 4466 {
4466 input.select(); 4467 input.select();
@@ -4474,7 +4475,7 @@ App.prototype.saveFile = function(forceDialog, success) @@ -4474,7 +4475,7 @@ App.prototype.saveFile = function(forceDialog, success)
4474 else 4475 else
4475 { 4476 {
4476 this.hideDialog(); 4477 this.hideDialog();
4477 - 4478 +
4478 if (prev == null && mode == App.MODE_DEVICE) 4479 if (prev == null && mode == App.MODE_DEVICE)
4479 { 4480 {
4480 if (file != null && EditorUi.nativeFileSupport) 4481 if (file != null && EditorUi.nativeFileSupport)
@@ -4513,7 +4514,7 @@ App.prototype.saveFile = function(forceDialog, success) @@ -4513,7 +4514,7 @@ App.prototype.saveFile = function(forceDialog, success)
4513 { 4514 {
4514 window.openFile = null; 4515 window.openFile = null;
4515 }); 4516 });
4516 - 4517 +
4517 // Do not use a filename to use undefined mode 4518 // Do not use a filename to use undefined mode
4518 window.openFile.setData(this.getFileData(true)); 4519 window.openFile.setData(this.getFileData(true));
4519 this.openLink(this.getUrl(window.location.pathname), null, true); 4520 this.openLink(this.getUrl(window.location.pathname), null, true);
@@ -4547,7 +4548,7 @@ App.prototype.saveFile = function(forceDialog, success) @@ -4547,7 +4548,7 @@ App.prototype.saveFile = function(forceDialog, success)
4547 4548
4548 /** 4549 /**
4549 * Translates this point by the given vector. 4550 * Translates this point by the given vector.
4550 - * 4551 + *
4551 * @param {number} dx X-coordinate of the translation. 4552 * @param {number} dx X-coordinate of the translation.
4552 * @param {number} dy Y-coordinate of the translation. 4553 * @param {number} dy Y-coordinate of the translation.
4553 */ 4554 */
@@ -4559,7 +4560,7 @@ App.prototype.loadTemplate = function(url, onload, onerror, templateFilename, as @@ -4559,7 +4560,7 @@ App.prototype.loadTemplate = function(url, onload, onerror, templateFilename, as
4559 var isVisioFilename = /(\.v(dx|sdx?))($|\?)/i.test(filterFn) || 4560 var isVisioFilename = /(\.v(dx|sdx?))($|\?)/i.test(filterFn) ||
4560 /(\.vs(x|sx?))($|\?)/i.test(filterFn); 4561 /(\.vs(x|sx?))($|\?)/i.test(filterFn);
4561 var binary = /\.png$/i.test(filterFn) || /\.pdf$/i.test(filterFn); 4562 var binary = /\.png$/i.test(filterFn) || /\.pdf$/i.test(filterFn);
4562 - 4563 +
4563 if (!this.editor.isCorsEnabledForUrl(realUrl)) 4564 if (!this.editor.isCorsEnabledForUrl(realUrl))
4564 { 4565 {
4565 base64 = binary || isVisioFilename; 4566 base64 = binary || isVisioFilename;
@@ -4574,7 +4575,7 @@ App.prototype.loadTemplate = function(url, onload, onerror, templateFilename, as @@ -4574,7 +4575,7 @@ App.prototype.loadTemplate = function(url, onload, onerror, templateFilename, as
4574 { 4575 {
4575 var data = (!base64) ? responseData : ((window.atob && !mxClient.IS_IE && !mxClient.IS_IE11) ? 4576 var data = (!base64) ? responseData : ((window.atob && !mxClient.IS_IE && !mxClient.IS_IE11) ?
4576 atob(responseData) : Base64.decode(responseData)); 4577 atob(responseData) : Base64.decode(responseData));
4577 - 4578 +
4578 if (isVisioFilename || this.isVisioData(data)) 4579 if (isVisioFilename || this.isVisioData(data))
4579 { 4580 {
4580 // Adds filename to control converter code 4581 // Adds filename to control converter code
@@ -4589,7 +4590,7 @@ App.prototype.loadTemplate = function(url, onload, onerror, templateFilename, as @@ -4589,7 +4590,7 @@ App.prototype.loadTemplate = function(url, onload, onerror, templateFilename, as
4589 filterFn = this.isRemoteVisioData(data) ? 'raw.vsd' : 'raw.vsdx'; 4590 filterFn = this.isRemoteVisioData(data) ? 'raw.vsd' : 'raw.vsdx';
4590 } 4591 }
4591 } 4592 }
4592 - 4593 +
4593 this.importVisio(this.base64ToBlob(responseData.substring(responseData.indexOf(',') + 1)), function(xml) 4594 this.importVisio(this.base64ToBlob(responseData.substring(responseData.indexOf(',') + 1)), function(xml)
4594 { 4595 {
4595 onload(xml); 4596 onload(xml);
@@ -4630,7 +4631,7 @@ App.prototype.loadTemplate = function(url, onload, onerror, templateFilename, as @@ -4630,7 +4631,7 @@ App.prototype.loadTemplate = function(url, onload, onerror, templateFilename, as
4630 { 4631 {
4631 data = Editor.extractGraphModelFromPng(responseData); 4632 data = Editor.extractGraphModelFromPng(responseData);
4632 } 4633 }
4633 - 4634 +
4634 onload(data); 4635 onload(data);
4635 } 4636 }
4636 } 4637 }
@@ -4644,7 +4645,7 @@ App.prototype.loadTemplate = function(url, onload, onerror, templateFilename, as @@ -4644,7 +4645,7 @@ App.prototype.loadTemplate = function(url, onload, onerror, templateFilename, as
4644 4645
4645 /** 4646 /**
4646 * Translates this point by the given vector. 4647 * Translates this point by the given vector.
4647 - * 4648 + *
4648 * @param {number} dx X-coordinate of the translation. 4649 * @param {number} dx X-coordinate of the translation.
4649 * @param {number} dy Y-coordinate of the translation. 4650 * @param {number} dy Y-coordinate of the translation.
4650 */ 4651 */
@@ -4682,7 +4683,7 @@ App.prototype.getPeerForMode = function(mode) @@ -4682,7 +4683,7 @@ App.prototype.getPeerForMode = function(mode)
4682 4683
4683 /** 4684 /**
4684 * Translates this point by the given vector. 4685 * Translates this point by the given vector.
4685 - * 4686 + *
4686 * @param {number} dx X-coordinate of the translation. 4687 * @param {number} dx X-coordinate of the translation.
4687 * @param {number} dy Y-coordinate of the translation. 4688 * @param {number} dy Y-coordinate of the translation.
4688 */ 4689 */
@@ -4693,16 +4694,16 @@ App.prototype.createFile = function(title, data, libs, mode, done, replace, fold @@ -4693,16 +4694,16 @@ App.prototype.createFile = function(title, data, libs, mode, done, replace, fold
4693 if (title != null && this.spinner.spin(document.body, mxResources.get('inserting'))) 4694 if (title != null && this.spinner.spin(document.body, mxResources.get('inserting')))
4694 { 4695 {
4695 data = (data != null) ? data : this.emptyDiagramXml; 4696 data = (data != null) ? data : this.emptyDiagramXml;
4696 - 4697 +
4697 var complete = mxUtils.bind(this, function() 4698 var complete = mxUtils.bind(this, function()
4698 { 4699 {
4699 this.spinner.stop(); 4700 this.spinner.stop();
4700 }); 4701 });
4701 - 4702 +
4702 var error = mxUtils.bind(this, function(resp) 4703 var error = mxUtils.bind(this, function(resp)
4703 { 4704 {
4704 complete(); 4705 complete();
4705 - 4706 +
4706 if (resp == null && this.getCurrentFile() == null && this.dialog == null) 4707 if (resp == null && this.getCurrentFile() == null && this.dialog == null)
4707 { 4708 {
4708 this.showSplash(); 4709 this.showSplash();
@@ -4712,7 +4713,7 @@ App.prototype.createFile = function(title, data, libs, mode, done, replace, fold @@ -4712,7 +4713,7 @@ App.prototype.createFile = function(title, data, libs, mode, done, replace, fold
4712 this.handleError(resp); 4713 this.handleError(resp);
4713 } 4714 }
4714 }); 4715 });
4715 - 4716 +
4716 try 4717 try
4717 { 4718 {
4718 if (mode == App.MODE_GOOGLE && this.drive != null) 4719 if (mode == App.MODE_GOOGLE && this.drive != null)
@@ -4721,7 +4722,7 @@ App.prototype.createFile = function(title, data, libs, mode, done, replace, fold @@ -4721,7 +4722,7 @@ App.prototype.createFile = function(title, data, libs, mode, done, replace, fold
4721 { 4722 {
4722 folderId = this.stateArg.folderId; 4723 folderId = this.stateArg.folderId;
4723 } 4724 }
4724 - 4725 +
4725 this.drive.insertFile(title, data, folderId, mxUtils.bind(this, function(file) 4726 this.drive.insertFile(title, data, folderId, mxUtils.bind(this, function(file)
4726 { 4727 {
4727 complete(); 4728 complete();
@@ -4779,11 +4780,11 @@ App.prototype.createFile = function(title, data, libs, mode, done, replace, fold @@ -4779,11 +4780,11 @@ App.prototype.createFile = function(title, data, libs, mode, done, replace, fold
4779 else if (!tempFile && mode == App.MODE_DEVICE && EditorUi.nativeFileSupport) 4780 else if (!tempFile && mode == App.MODE_DEVICE && EditorUi.nativeFileSupport)
4780 { 4781 {
4781 complete(); 4782 complete();
4782 - 4783 +
4783 this.showSaveFilePicker(mxUtils.bind(this, function(fileHandle, desc) 4784 this.showSaveFilePicker(mxUtils.bind(this, function(fileHandle, desc)
4784 { 4785 {
4785 var file = new LocalFile(this, data, desc.name, null, fileHandle, desc); 4786 var file = new LocalFile(this, data, desc.name, null, fileHandle, desc);
4786 - 4787 +
4787 file.saveFile(desc.name, false, mxUtils.bind(this, function() 4788 file.saveFile(desc.name, false, mxUtils.bind(this, function()
4788 { 4789 {
4789 this.fileCreated(file, libs, replace, done, clibs); 4790 this.fileCreated(file, libs, replace, done, clibs);
@@ -4812,14 +4813,14 @@ App.prototype.createFile = function(title, data, libs, mode, done, replace, fold @@ -4812,14 +4813,14 @@ App.prototype.createFile = function(title, data, libs, mode, done, replace, fold
4812 4813
4813 /** 4814 /**
4814 * Translates this point by the given vector. 4815 * Translates this point by the given vector.
4815 - * 4816 + *
4816 * @param {number} dx X-coordinate of the translation. 4817 * @param {number} dx X-coordinate of the translation.
4817 * @param {number} dy Y-coordinate of the translation. 4818 * @param {number} dy Y-coordinate of the translation.
4818 */ 4819 */
4819 App.prototype.fileCreated = function(file, libs, replace, done, clibs) 4820 App.prototype.fileCreated = function(file, libs, replace, done, clibs)
4820 { 4821 {
4821 var url = window.location.pathname; 4822 var url = window.location.pathname;
4822 - 4823 +
4823 if (libs != null && libs.length > 0) 4824 if (libs != null && libs.length > 0)
4824 { 4825 {
4825 url += '?libs=' + libs; 4826 url += '?libs=' + libs;
@@ -4829,7 +4830,7 @@ App.prototype.fileCreated = function(file, libs, replace, done, clibs) @@ -4829,7 +4830,7 @@ App.prototype.fileCreated = function(file, libs, replace, done, clibs)
4829 { 4830 {
4830 url += '?clibs=' + clibs; 4831 url += '?clibs=' + clibs;
4831 } 4832 }
4832 - 4833 +
4833 url = this.getUrl(url); 4834 url = this.getUrl(url);
4834 4835
4835 // Always opens a new tab for local files to avoid losing changes 4836 // Always opens a new tab for local files to avoid losing changes
@@ -4848,7 +4849,7 @@ App.prototype.fileCreated = function(file, libs, replace, done, clibs) @@ -4848,7 +4849,7 @@ App.prototype.fileCreated = function(file, libs, replace, done, clibs)
4848 var redirect = window.location.protocol + '//' + window.location.hostname + url; 4849 var redirect = window.location.protocol + '//' + window.location.hostname + url;
4849 var node = dataNode; 4850 var node = dataNode;
4850 var graph = null; 4851 var graph = null;
4851 - 4852 +
4852 // Handles special case where SVG files need a rendered graph to be saved 4853 // Handles special case where SVG files need a rendered graph to be saved
4853 if (dataNode != null && /\.svg$/i.test(file.getTitle())) 4854 if (dataNode != null && /\.svg$/i.test(file.getTitle()))
4854 { 4855 {
@@ -4856,7 +4857,7 @@ App.prototype.fileCreated = function(file, libs, replace, done, clibs) @@ -4856,7 +4857,7 @@ App.prototype.fileCreated = function(file, libs, replace, done, clibs)
4856 document.body.appendChild(graph.container); 4857 document.body.appendChild(graph.container);
4857 node = this.decodeNodeIntoGraph(node, graph); 4858 node = this.decodeNodeIntoGraph(node, graph);
4858 } 4859 }
4859 - 4860 +
4860 file.setData(this.createFileData(dataNode, graph, file, redirect)); 4861 file.setData(this.createFileData(dataNode, graph, file, redirect));
4861 4862
4862 if (graph != null) 4863 if (graph != null)
@@ -4868,43 +4869,43 @@ App.prototype.fileCreated = function(file, libs, replace, done, clibs) @@ -4868,43 +4869,43 @@ App.prototype.fileCreated = function(file, libs, replace, done, clibs)
4868 { 4869 {
4869 this.spinner.stop(); 4870 this.spinner.stop();
4870 }); 4871 });
4871 - 4872 +
4872 var fn = mxUtils.bind(this, function() 4873 var fn = mxUtils.bind(this, function()
4873 { 4874 {
4874 complete(); 4875 complete();
4875 - 4876 +
4876 var currentFile = this.getCurrentFile(); 4877 var currentFile = this.getCurrentFile();
4877 - 4878 +
4878 if (replace == null && currentFile != null) 4879 if (replace == null && currentFile != null)
4879 { 4880 {
4880 replace = !currentFile.isModified() && currentFile.getMode() == null; 4881 replace = !currentFile.isModified() && currentFile.getMode() == null;
4881 } 4882 }
4882 - 4883 +
4883 var fn3 = mxUtils.bind(this, function() 4884 var fn3 = mxUtils.bind(this, function()
4884 { 4885 {
4885 window.openFile = null; 4886 window.openFile = null;
4886 this.fileLoaded(file); 4887 this.fileLoaded(file);
4887 - 4888 +
4888 if (replace) 4889 if (replace)
4889 { 4890 {
4890 file.addAllSavedStatus(); 4891 file.addAllSavedStatus();
4891 } 4892 }
4892 - 4893 +
4893 if (libs != null) 4894 if (libs != null)
4894 { 4895 {
4895 this.sidebar.showEntries(libs); 4896 this.sidebar.showEntries(libs);
4896 } 4897 }
4897 - 4898 +
4898 if (clibs != null) 4899 if (clibs != null)
4899 { 4900 {
4900 var temp = []; 4901 var temp = [];
4901 var tokens = clibs.split(';'); 4902 var tokens = clibs.split(';');
4902 - 4903 +
4903 for (var i = 0; i < tokens.length; i++) 4904 for (var i = 0; i < tokens.length; i++)
4904 { 4905 {
4905 temp.push(decodeURIComponent(tokens[i])); 4906 temp.push(decodeURIComponent(tokens[i]));
4906 } 4907 }
4907 - 4908 +
4908 this.loadLibraries(temp); 4909 this.loadLibraries(temp);
4909 } 4910 }
4910 }); 4911 });
@@ -4926,7 +4927,7 @@ App.prototype.fileCreated = function(file, libs, replace, done, clibs) @@ -4926,7 +4927,7 @@ App.prototype.fileCreated = function(file, libs, replace, done, clibs)
4926 { 4927 {
4927 done(); 4928 done();
4928 } 4929 }
4929 - 4930 +
4930 // Opens the file in a new window 4931 // Opens the file in a new window
4931 if (replace != null && !replace) 4932 if (replace != null && !replace)
4932 { 4933 {
@@ -4937,7 +4938,7 @@ App.prototype.fileCreated = function(file, libs, replace, done, clibs) @@ -4937,7 +4938,7 @@ App.prototype.fileCreated = function(file, libs, replace, done, clibs)
4937 { 4938 {
4938 window.openFile = null; 4939 window.openFile = null;
4939 }); 4940 });
4940 - 4941 +
4941 window.openFile.setData(file.getData(), file.getTitle(), file.getMode() == null); 4942 window.openFile.setData(file.getData(), file.getTitle(), file.getMode() == null);
4942 } 4943 }
4943 4944
@@ -4945,7 +4946,7 @@ App.prototype.fileCreated = function(file, libs, replace, done, clibs) @@ -4945,7 +4946,7 @@ App.prototype.fileCreated = function(file, libs, replace, done, clibs)
4945 { 4946 {
4946 done(); 4947 done();
4947 } 4948 }
4948 - 4949 +
4949 window.openWindow(url, null, fn2); 4950 window.openWindow(url, null, fn2);
4950 } 4951 }
4951 else 4952 else
@@ -4953,7 +4954,7 @@ App.prototype.fileCreated = function(file, libs, replace, done, clibs) @@ -4953,7 +4954,7 @@ App.prototype.fileCreated = function(file, libs, replace, done, clibs)
4953 fn2(); 4954 fn2();
4954 } 4955 }
4955 }); 4956 });
4956 - 4957 +
4957 // Updates data in memory for local files 4958 // Updates data in memory for local files
4958 if (file.constructor == LocalFile) 4959 if (file.constructor == LocalFile)
4959 { 4960 {
@@ -5422,19 +5423,19 @@ App.prototype.loadFile = function (id, sameWindow, file, success, force) { @@ -5422,19 +5423,19 @@ App.prototype.loadFile = function (id, sameWindow, file, success, force) {
5422 }; 5423 };
5423 /** 5424 /**
5424 * Translates this point by the given vector. 5425 * Translates this point by the given vector.
5425 - * 5426 + *
5426 * @param {number} dx X-coordinate of the translation. 5427 * @param {number} dx X-coordinate of the translation.
5427 * @param {number} dy Y-coordinate of the translation. 5428 * @param {number} dy Y-coordinate of the translation.
5428 */ 5429 */
5429 App.prototype.getLibraryStorageHint = function(file) 5430 App.prototype.getLibraryStorageHint = function(file)
5430 { 5431 {
5431 var tip = file.getTitle(); 5432 var tip = file.getTitle();
5432 - 5433 +
5433 if (file.constructor != LocalLibrary) 5434 if (file.constructor != LocalLibrary)
5434 { 5435 {
5435 tip += '\n' + file.getHash(); 5436 tip += '\n' + file.getHash();
5436 } 5437 }
5437 - 5438 +
5438 if (file.constructor == DriveLibrary) 5439 if (file.constructor == DriveLibrary)
5439 { 5440 {
5440 tip += ' (' + mxResources.get('googleDrive') + ')'; 5441 tip += ' (' + mxResources.get('googleDrive') + ')';
@@ -5502,7 +5503,7 @@ App.prototype.loadLibraries = function(libs, done) @@ -5502,7 +5503,7 @@ App.prototype.loadLibraries = function(libs, done)
5502 { 5503 {
5503 this.loadedLibraries = new Object(); 5504 this.loadedLibraries = new Object();
5504 } 5505 }
5505 - 5506 +
5506 // Ignores this library next time 5507 // Ignores this library next time
5507 var ignore = mxUtils.bind(this, function(id, keep) 5508 var ignore = mxUtils.bind(this, function(id, keep)
5508 { 5509 {
@@ -5533,20 +5534,20 @@ App.prototype.loadLibraries = function(libs, done) @@ -5533,20 +5534,20 @@ App.prototype.loadLibraries = function(libs, done)
5533 } 5534 }
5534 } 5535 }
5535 } 5536 }
5536 - 5537 +
5537 if (done != null) 5538 if (done != null)
5538 { 5539 {
5539 done(); 5540 done();
5540 } 5541 }
5541 } 5542 }
5542 }); 5543 });
5543 - 5544 +
5544 if (libs != null) 5545 if (libs != null)
5545 { 5546 {
5546 for (var i = 0; i < libs.length; i++) 5547 for (var i = 0; i < libs.length; i++)
5547 { 5548 {
5548 var name = encodeURIComponent(decodeURIComponent(libs[i])); 5549 var name = encodeURIComponent(decodeURIComponent(libs[i]));
5549 - 5550 +
5550 (mxUtils.bind(this, function(id, index) 5551 (mxUtils.bind(this, function(id, index)
5551 { 5552 {
5552 if (id != null && id.length > 0 && this.loadedLibraries[id] == null && 5553 if (id != null && id.length > 0 && this.loadedLibraries[id] == null &&
@@ -5555,23 +5556,23 @@ App.prototype.loadLibraries = function(libs, done) @@ -5555,23 +5556,23 @@ App.prototype.loadLibraries = function(libs, done)
5555 // Waits for all libraries to load 5556 // Waits for all libraries to load
5556 this.loadedLibraries[id] = true; 5557 this.loadedLibraries[id] = true;
5557 waiting++; 5558 waiting++;
5558 - 5559 +
5559 var onload = mxUtils.bind(this, function(file) 5560 var onload = mxUtils.bind(this, function(file)
5560 { 5561 {
5561 files[index] = file; 5562 files[index] = file;
5562 waiting--; 5563 waiting--;
5563 checkDone(); 5564 checkDone();
5564 }); 5565 });
5565 - 5566 +
5566 var onerror = mxUtils.bind(this, function(keep) 5567 var onerror = mxUtils.bind(this, function(keep)
5567 { 5568 {
5568 ignore(id, keep); 5569 ignore(id, keep);
5569 waiting--; 5570 waiting--;
5570 checkDone(); 5571 checkDone();
5571 }); 5572 });
5572 - 5573 +
5573 var service = id.substring(0, 1); 5574 var service = id.substring(0, 1);
5574 - 5575 +
5575 if (service == 'L') 5576 if (service == 'L')
5576 { 5577 {
5577 if (isLocalStorage || mxClient.IS_CHROMEAPP) 5578 if (isLocalStorage || mxClient.IS_CHROMEAPP)
@@ -5582,14 +5583,14 @@ App.prototype.loadLibraries = function(libs, done) @@ -5582,14 +5583,14 @@ App.prototype.loadLibraries = function(libs, done)
5582 try 5583 try
5583 { 5584 {
5584 var name = decodeURIComponent(id.substring(1)); 5585 var name = decodeURIComponent(id.substring(1));
5585 - 5586 +
5586 StorageFile.getFileContent(this, name, mxUtils.bind(this, function(xml) 5587 StorageFile.getFileContent(this, name, mxUtils.bind(this, function(xml)
5587 { 5588 {
5588 if (name == '.scratchpad' && xml == null) 5589 if (name == '.scratchpad' && xml == null)
5589 { 5590 {
5590 xml = this.emptyLibraryXml; 5591 xml = this.emptyLibraryXml;
5591 } 5592 }
5592 - 5593 +
5593 if (xml != null) 5594 if (xml != null)
5594 { 5595 {
5595 onload(new StorageLibrary(this, xml, name)); 5596 onload(new StorageLibrary(this, xml, name));
@@ -5610,7 +5611,7 @@ App.prototype.loadLibraries = function(libs, done) @@ -5610,7 +5611,7 @@ App.prototype.loadLibraries = function(libs, done)
5610 else if (service == 'U') 5611 else if (service == 'U')
5611 { 5612 {
5612 var url = decodeURIComponent(id.substring(1)); 5613 var url = decodeURIComponent(id.substring(1));
5613 - 5614 +
5614 if (!this.isOffline()) 5615 if (!this.isOffline())
5615 { 5616 {
5616 this.loadTemplate(url, mxUtils.bind(this, function(text) 5617 this.loadTemplate(url, mxUtils.bind(this, function(text)
@@ -5633,16 +5634,16 @@ App.prototype.loadLibraries = function(libs, done) @@ -5633,16 +5634,16 @@ App.prototype.loadLibraries = function(libs, done)
5633 else if (service == 'R') 5634 else if (service == 'R')
5634 { 5635 {
5635 var libDesc = decodeURIComponent(id.substring(1)); 5636 var libDesc = decodeURIComponent(id.substring(1));
5636 - 5637 +
5637 try 5638 try
5638 { 5639 {
5639 libDesc = JSON.parse(libDesc); 5640 libDesc = JSON.parse(libDesc);
5640 var libObj = { 5641 var libObj = {
5641 - id: libDesc[0],  
5642 - title: libDesc[1], 5642 + id: libDesc[0],
  5643 + title: libDesc[1],
5643 downloadUrl: libDesc[2] 5644 downloadUrl: libDesc[2]
5644 } 5645 }
5645 - 5646 +
5646 this.remoteInvoke('getFileContent', [libObj.downloadUrl], null, mxUtils.bind(this, function(libContent) 5647 this.remoteInvoke('getFileContent', [libObj.downloadUrl], null, mxUtils.bind(this, function(libContent)
5647 { 5648 {
5648 try 5649 try
@@ -5680,7 +5681,7 @@ App.prototype.loadLibraries = function(libs, done) @@ -5680,7 +5681,7 @@ App.prototype.loadLibraries = function(libs, done)
5680 else 5681 else
5681 { 5682 {
5682 var peer = null; 5683 var peer = null;
5683 - 5684 +
5684 if (service == 'G') 5685 if (service == 'G')
5685 { 5686 {
5686 if (this.drive != null && this.drive.user != null) 5687 if (this.drive != null && this.drive.user != null)
@@ -5716,7 +5717,7 @@ App.prototype.loadLibraries = function(libs, done) @@ -5716,7 +5717,7 @@ App.prototype.loadLibraries = function(libs, done)
5716 peer = this.oneDrive; 5717 peer = this.oneDrive;
5717 } 5718 }
5718 } 5719 }
5719 - 5720 +
5720 if (peer != null) 5721 if (peer != null)
5721 { 5722 {
5722 peer.getLibrary(decodeURIComponent(id.substring(1)), mxUtils.bind(this, function(file) 5723 peer.getLibrary(decodeURIComponent(id.substring(1)), mxUtils.bind(this, function(file)
@@ -5742,7 +5743,7 @@ App.prototype.loadLibraries = function(libs, done) @@ -5742,7 +5743,7 @@ App.prototype.loadLibraries = function(libs, done)
5742 } 5743 }
5743 }))(name, i); 5744 }))(name, i);
5744 } 5745 }
5745 - 5746 +
5746 checkDone(); 5747 checkDone();
5747 } 5748 }
5748 else 5749 else
@@ -5754,7 +5755,7 @@ App.prototype.loadLibraries = function(libs, done) @@ -5754,7 +5755,7 @@ App.prototype.loadLibraries = function(libs, done)
5754 5755
5755 /** 5756 /**
5756 * Translates this point by the given vector. 5757 * Translates this point by the given vector.
5757 - * 5758 + *
5758 * @param {number} dx X-coordinate of the translation. 5759 * @param {number} dx X-coordinate of the translation.
5759 * @param {number} dy Y-coordinate of the translation. 5760 * @param {number} dy Y-coordinate of the translation.
5760 */ 5761 */
@@ -5763,7 +5764,7 @@ App.prototype.updateButtonContainer = function() @@ -5763,7 +5764,7 @@ App.prototype.updateButtonContainer = function()
5763 if (this.buttonContainer != null) 5764 if (this.buttonContainer != null)
5764 { 5765 {
5765 var file = this.getCurrentFile(); 5766 var file = this.getCurrentFile();
5766 - 5767 +
5767 if (urlParams['embed'] == '1') 5768 if (urlParams['embed'] == '1')
5768 { 5769 {
5769 if (uiTheme == 'atlas' || urlParams['atlas'] == '1') 5770 if (uiTheme == 'atlas' || urlParams['atlas'] == '1')
@@ -5778,7 +5779,7 @@ App.prototype.updateButtonContainer = function() @@ -5778,7 +5779,7 @@ App.prototype.updateButtonContainer = function()
5778 this.buttonContainer.style.paddingTop = '6px'; 5779 this.buttonContainer.style.paddingTop = '6px';
5779 } 5780 }
5780 } 5781 }
5781 - 5782 +
5782 // Comments 5783 // Comments
5783 if (this.commentsSupported() && urlParams['sketch'] != '1') 5784 if (this.commentsSupported() && urlParams['sketch'] != '1')
5784 { 5785 {
@@ -5791,7 +5792,7 @@ App.prototype.updateButtonContainer = function() @@ -5791,7 +5792,7 @@ App.prototype.updateButtonContainer = function()
5791 'margin-right:4px;float:left;cursor:pointer;width:24px;height:24px;background-size:24px 24px;' + 5792 'margin-right:4px;float:left;cursor:pointer;width:24px;height:24px;background-size:24px 24px;' +
5792 'background-position:center center;background-repeat:no-repeat;background-image:' + 5793 'background-position:center center;background-repeat:no-repeat;background-image:' +
5793 'url(' + Editor.commentImage + ');'; 5794 'url(' + Editor.commentImage + ');';
5794 - 5795 +
5795 if (uiTheme == 'atlas') 5796 if (uiTheme == 'atlas')
5796 { 5797 {
5797 this.commentButton.style.marginRight = '10px'; 5798 this.commentButton.style.marginRight = '10px';
@@ -5809,14 +5810,14 @@ App.prototype.updateButtonContainer = function() @@ -5809,14 +5810,14 @@ App.prototype.updateButtonContainer = function()
5809 { 5810 {
5810 this.commentButton.style.marginTop = '-5px'; 5811 this.commentButton.style.marginTop = '-5px';
5811 } 5812 }
5812 - 5813 +
5813 mxEvent.addListener(this.commentButton, 'click', mxUtils.bind(this, function() 5814 mxEvent.addListener(this.commentButton, 'click', mxUtils.bind(this, function()
5814 { 5815 {
5815 this.actions.get('comments').funct(); 5816 this.actions.get('comments').funct();
5816 })); 5817 }));
5817 - 5818 +
5818 this.buttonContainer.appendChild(this.commentButton); 5819 this.buttonContainer.appendChild(this.commentButton);
5819 - 5820 +
5820 if (uiTheme == 'dark' || uiTheme == 'atlas') 5821 if (uiTheme == 'dark' || uiTheme == 'atlas')
5821 { 5822 {
5822 this.commentButton.style.filter = 'invert(100%)'; 5823 this.commentButton.style.filter = 'invert(100%)';
@@ -5828,7 +5829,7 @@ App.prototype.updateButtonContainer = function() @@ -5828,7 +5829,7 @@ App.prototype.updateButtonContainer = function()
5828 this.commentButton.parentNode.removeChild(this.commentButton); 5829 this.commentButton.parentNode.removeChild(this.commentButton);
5829 this.commentButton = null; 5830 this.commentButton = null;
5830 } 5831 }
5831 - 5832 +
5832 // Share 5833 // Share
5833 if (urlParams['embed'] != '1' && this.getServiceName() == 'draw.io' && 5834 if (urlParams['embed'] != '1' && this.getServiceName() == 'draw.io' &&
5834 !mxClient.IS_CHROMEAPP && !EditorUi.isElectronApp && 5835 !mxClient.IS_CHROMEAPP && !EditorUi.isElectronApp &&
@@ -5851,27 +5852,27 @@ App.prototype.updateButtonContainer = function() @@ -5851,27 +5852,27 @@ App.prototype.updateButtonContainer = function()
5851 this.shareButton.style.minWidth = '0px'; 5852 this.shareButton.style.minWidth = '0px';
5852 this.shareButton.style.cssFloat = 'right'; 5853 this.shareButton.style.cssFloat = 'right';
5853 this.shareButton.setAttribute('title', mxResources.get('share')); 5854 this.shareButton.setAttribute('title', mxResources.get('share'));
5854 - 5855 +
5855 var icon = document.createElement('img'); 5856 var icon = document.createElement('img');
5856 icon.setAttribute('src', this.shareImage); 5857 icon.setAttribute('src', this.shareImage);
5857 icon.setAttribute('align', 'absmiddle'); 5858 icon.setAttribute('align', 'absmiddle');
5858 icon.style.marginRight = '4px'; 5859 icon.style.marginRight = '4px';
5859 icon.style.marginTop = '-3px'; 5860 icon.style.marginTop = '-3px';
5860 this.shareButton.appendChild(icon); 5861 this.shareButton.appendChild(icon);
5861 - 5862 +
5862 if (!Editor.isDarkMode() && uiTheme != 'atlas') 5863 if (!Editor.isDarkMode() && uiTheme != 'atlas')
5863 { 5864 {
5864 this.shareButton.style.color = 'black'; 5865 this.shareButton.style.color = 'black';
5865 icon.style.filter = 'invert(100%)'; 5866 icon.style.filter = 'invert(100%)';
5866 } 5867 }
5867 - 5868 +
5868 mxUtils.write(this.shareButton, mxResources.get('share')); 5869 mxUtils.write(this.shareButton, mxResources.get('share'));
5869 - 5870 +
5870 mxEvent.addListener(this.shareButton, 'click', mxUtils.bind(this, function() 5871 mxEvent.addListener(this.shareButton, 'click', mxUtils.bind(this, function()
5871 { 5872 {
5872 this.actions.get('share').funct(); 5873 this.actions.get('share').funct();
5873 })); 5874 }));
5874 - 5875 +
5875 this.buttonContainer.appendChild(this.shareButton); 5876 this.buttonContainer.appendChild(this.shareButton);
5876 } 5877 }
5877 } 5878 }
@@ -5880,7 +5881,7 @@ App.prototype.updateButtonContainer = function() @@ -5880,7 +5881,7 @@ App.prototype.updateButtonContainer = function()
5880 this.shareButton.parentNode.removeChild(this.shareButton); 5881 this.shareButton.parentNode.removeChild(this.shareButton);
5881 this.shareButton = null; 5882 this.shareButton = null;
5882 } 5883 }
5883 - 5884 +
5884 //Fetch notifications 5885 //Fetch notifications
5885 if (urlParams['extAuth'] != '1') //Disable notification with external auth (e.g, Teams app) 5886 if (urlParams['extAuth'] != '1') //Disable notification with external auth (e.g, Teams app)
5886 { 5887 {
@@ -5899,32 +5900,32 @@ App.prototype.fetchAndShowNotification = function(target, subtarget) @@ -5899,32 +5900,32 @@ App.prototype.fetchAndShowNotification = function(target, subtarget)
5899 { 5900 {
5900 if (this.fetchingNotif) 5901 if (this.fetchingNotif)
5901 { 5902 {
5902 - return; 5903 + return;
5903 } 5904 }
5904 - 5905 +
5905 target = target || 'online'; 5906 target = target || 'online';
5906 var cachedNotifKey = '.notifCache'; 5907 var cachedNotifKey = '.notifCache';
5907 var cachedNotif = null; 5908 var cachedNotif = null;
5908 - 5909 +
5909 var processNotif = mxUtils.bind(this, function(notifs) 5910 var processNotif = mxUtils.bind(this, function(notifs)
5910 { 5911 {
5911 notifs = notifs.filter(function(notif) 5912 notifs = notifs.filter(function(notif)
5912 { 5913 {
5913 - return !notif.targets || notif.targets.indexOf(target) > -1 || 5914 + return !notif.targets || notif.targets.indexOf(target) > -1 ||
5914 (subtarget != null && notif.targets.indexOf(subtarget) > -1); 5915 (subtarget != null && notif.targets.indexOf(subtarget) > -1);
5915 }); 5916 });
5916 - 5917 +
5917 var lsReadFlag = target + 'NotifReadTS'; 5918 var lsReadFlag = target + 'NotifReadTS';
5918 var lastRead = (localStorage != null) ? parseInt(localStorage.getItem(lsReadFlag)) : true; 5919 var lastRead = (localStorage != null) ? parseInt(localStorage.getItem(lsReadFlag)) : true;
5919 - 5920 +
5920 for (var i = 0; i < notifs.length; i++) 5921 for (var i = 0; i < notifs.length; i++)
5921 { 5922 {
5922 notifs[i].isNew = (!lastRead || notifs[i].timestamp > lastRead); 5923 notifs[i].isNew = (!lastRead || notifs[i].timestamp > lastRead);
5923 } 5924 }
5924 - 5925 +
5925 this.showNotification(notifs, lsReadFlag); 5926 this.showNotification(notifs, lsReadFlag);
5926 }); 5927 });
5927 - 5928 +
5928 try 5929 try
5929 { 5930 {
5930 if (localStorage != null) 5931 if (localStorage != null)
@@ -5933,7 +5934,7 @@ App.prototype.fetchAndShowNotification = function(target, subtarget) @@ -5933,7 +5934,7 @@ App.prototype.fetchAndShowNotification = function(target, subtarget)
5933 } 5934 }
5934 } 5935 }
5935 catch(e) {} //Ignore 5936 catch(e) {} //Ignore
5936 - 5937 +
5937 if (cachedNotif == null || cachedNotif.ts + 24 * 60 * 60 * 1000 < Date.now()) //Cache for one day 5938 if (cachedNotif == null || cachedNotif.ts + 24 * 60 * 60 * 1000 < Date.now()) //Cache for one day
5938 { 5939 {
5939 this.fetchingNotif = true; 5940 this.fetchingNotif = true;
@@ -5943,7 +5944,7 @@ App.prototype.fetchAndShowNotification = function(target, subtarget) @@ -5943,7 +5944,7 @@ App.prototype.fetchAndShowNotification = function(target, subtarget)
5943 if (req.getStatus() >= 200 && req.getStatus() <= 299) 5944 if (req.getStatus() >= 200 && req.getStatus() <= 299)
5944 { 5945 {
5945 var notifs = JSON.parse(req.getText()); 5946 var notifs = JSON.parse(req.getText());
5946 - 5947 +
5947 //Process and sort 5948 //Process and sort
5948 notifs.sort(function(a, b) 5949 notifs.sort(function(a, b)
5949 { 5950 {
@@ -5954,8 +5955,8 @@ App.prototype.fetchAndShowNotification = function(target, subtarget) @@ -5954,8 +5955,8 @@ App.prototype.fetchAndShowNotification = function(target, subtarget)
5954 { 5955 {
5955 localStorage.setItem(cachedNotifKey, JSON.stringify({ts: Date.now(), notifs: notifs})); 5956 localStorage.setItem(cachedNotifKey, JSON.stringify({ts: Date.now(), notifs: notifs}));
5956 } 5957 }
5957 -  
5958 - this.fetchingNotif = false; 5958 +
  5959 + this.fetchingNotif = false;
5959 processNotif(notifs); 5960 processNotif(notifs);
5960 } 5961 }
5961 })); 5962 }));
@@ -5990,19 +5991,19 @@ App.prototype.showNotification = function(notifs, lsReadFlag) @@ -5990,19 +5991,19 @@ App.prototype.showNotification = function(notifs, lsReadFlag)
5990 this.notificationBtn.style.display = 'none'; 5991 this.notificationBtn.style.display = 'none';
5991 this.editor.fireEvent(new mxEventObject('statusChanged')); 5992 this.editor.fireEvent(new mxEventObject('statusChanged'));
5992 } 5993 }
5993 - 5994 +
5994 return; 5995 return;
5995 } 5996 }
5996 - 5997 +
5997 function shouldAnimate(newNotif) 5998 function shouldAnimate(newNotif)
5998 { 5999 {
5999 var countEl = document.querySelector('.geNotification-count'); 6000 var countEl = document.querySelector('.geNotification-count');
6000 - 6001 +
6001 if (countEl == null) 6002 if (countEl == null)
6002 { 6003 {
6003 return; 6004 return;
6004 } 6005 }
6005 - 6006 +
6006 countEl.innerHTML = newNotif; 6007 countEl.innerHTML = newNotif;
6007 countEl.style.display = newNotif == 0? 'none' : ''; 6008 countEl.style.display = newNotif == 0? 'none' : '';
6008 var notifBell = document.querySelector('.geNotification-bell'); 6009 var notifBell = document.querySelector('.geNotification-bell');
@@ -6010,28 +6011,28 @@ App.prototype.showNotification = function(notifs, lsReadFlag) @@ -6010,28 +6011,28 @@ App.prototype.showNotification = function(notifs, lsReadFlag)
6010 notifBell.className = 'geNotification-bell' + (newNotif == 0? ' geNotification-bellOff' : ''); 6011 notifBell.className = 'geNotification-bell' + (newNotif == 0? ' geNotification-bellOff' : '');
6011 document.querySelector('.geBell-rad').style.animation = newNotif == 0? 'none' : ''; 6012 document.querySelector('.geBell-rad').style.animation = newNotif == 0? 'none' : '';
6012 } 6013 }
6013 - 6014 +
6014 var markAllAsRead = mxUtils.bind(this, function() 6015 var markAllAsRead = mxUtils.bind(this, function()
6015 { 6016 {
6016 this.notificationWin.style.display = 'none'; 6017 this.notificationWin.style.display = 'none';
6017 var unread = this.notificationWin.querySelectorAll('.circle.active'); 6018 var unread = this.notificationWin.querySelectorAll('.circle.active');
6018 - 6019 +
6019 for (var i = 0; i < unread.length; i++) 6020 for (var i = 0; i < unread.length; i++)
6020 { 6021 {
6021 unread[i].className = 'circle'; 6022 unread[i].className = 'circle';
6022 } 6023 }
6023 - 6024 +
6024 if (isLocalStorage && notifs[0]) 6025 if (isLocalStorage && notifs[0])
6025 { 6026 {
6026 localStorage.setItem(lsReadFlag, notifs[0].timestamp); 6027 localStorage.setItem(lsReadFlag, notifs[0].timestamp);
6027 } 6028 }
6028 }); 6029 });
6029 - 6030 +
6030 if (this.notificationBtn == null) 6031 if (this.notificationBtn == null)
6031 { 6032 {
6032 this.notificationBtn = document.createElement('div'); 6033 this.notificationBtn = document.createElement('div');
6033 this.notificationBtn.className = 'geNotification-box'; 6034 this.notificationBtn.className = 'geNotification-box';
6034 - 6035 +
6035 if (uiTheme == 'min') 6036 if (uiTheme == 'min')
6036 { 6037 {
6037 this.notificationBtn.style.width = '30px'; 6038 this.notificationBtn.style.width = '30px';
@@ -6041,11 +6042,11 @@ App.prototype.showNotification = function(notifs, lsReadFlag) @@ -6041,11 +6042,11 @@ App.prototype.showNotification = function(notifs, lsReadFlag)
6041 { 6042 {
6042 this.notificationBtn.style.top = '2px'; 6043 this.notificationBtn.style.top = '2px';
6043 } 6044 }
6044 - 6045 +
6045 var notifCount = document.createElement('span'); 6046 var notifCount = document.createElement('span');
6046 notifCount.className = 'geNotification-count'; 6047 notifCount.className = 'geNotification-count';
6047 this.notificationBtn.appendChild(notifCount); 6048 this.notificationBtn.appendChild(notifCount);
6048 - 6049 +
6049 var notifBell = document.createElement('div'); 6050 var notifBell = document.createElement('div');
6050 notifBell.className = 'geNotification-bell'; 6051 notifBell.className = 'geNotification-bell';
6051 notifBell.style.opacity = uiTheme == 'min'? '0.5' : ''; 6052 notifBell.style.opacity = uiTheme == 'min'? '0.5' : '';
@@ -6062,15 +6063,15 @@ App.prototype.showNotification = function(notifs, lsReadFlag) @@ -6062,15 +6063,15 @@ App.prototype.showNotification = function(notifs, lsReadFlag)
6062 bellPart.className = 'geBell-rad'; 6063 bellPart.className = 'geBell-rad';
6063 notifBell.appendChild(bellPart); 6064 notifBell.appendChild(bellPart);
6064 this.notificationBtn.appendChild(notifBell); 6065 this.notificationBtn.appendChild(notifBell);
6065 - 6066 +
6066 //Add as first child such that it is the left-most one 6067 //Add as first child such that it is the left-most one
6067 this.buttonContainer.insertBefore(this.notificationBtn, this.buttonContainer.firstChild); 6068 this.buttonContainer.insertBefore(this.notificationBtn, this.buttonContainer.firstChild);
6068 - 6069 +
6069 this.notificationWin = document.createElement('div'); 6070 this.notificationWin = document.createElement('div');
6070 this.notificationWin.className = 'geNotifPanel'; 6071 this.notificationWin.className = 'geNotifPanel';
6071 this.notificationWin.style.display = 'none'; 6072 this.notificationWin.style.display = 'none';
6072 document.body.appendChild(this.notificationWin); 6073 document.body.appendChild(this.notificationWin);
6073 - 6074 +
6074 var winHeader = document.createElement('div'); 6075 var winHeader = document.createElement('div');
6075 winHeader.className = 'header'; 6076 winHeader.className = 'header';
6076 var winTitle = document.createElement('span'); 6077 var winTitle = document.createElement('span');
@@ -6082,7 +6083,7 @@ App.prototype.showNotification = function(notifs, lsReadFlag) @@ -6082,7 +6083,7 @@ App.prototype.showNotification = function(notifs, lsReadFlag)
6082 winClose.textContent = 'x'; 6083 winClose.textContent = 'x';
6083 winHeader.appendChild(winClose); 6084 winHeader.appendChild(winClose);
6084 this.notificationWin.appendChild(winHeader); 6085 this.notificationWin.appendChild(winHeader);
6085 - 6086 +
6086 var winBody = document.createElement('div'); 6087 var winBody = document.createElement('div');
6087 winBody.className = 'notifications clearfix'; 6088 winBody.className = 'notifications clearfix';
6088 var notifList = document.createElement('div'); 6089 var notifList = document.createElement('div');
@@ -6090,7 +6091,7 @@ App.prototype.showNotification = function(notifs, lsReadFlag) @@ -6090,7 +6091,7 @@ App.prototype.showNotification = function(notifs, lsReadFlag)
6090 notifList.style.position = 'relative'; 6091 notifList.style.position = 'relative';
6091 winBody.appendChild(notifList); 6092 winBody.appendChild(notifList);
6092 this.notificationWin.appendChild(winBody); 6093 this.notificationWin.appendChild(winBody);
6093 - 6094 +
6094 mxEvent.addListener(this.notificationBtn, 'click', mxUtils.bind(this, function() 6095 mxEvent.addListener(this.notificationBtn, 'click', mxUtils.bind(this, function()
6095 { 6096 {
6096 if (this.notificationWin.style.display == 'none') 6097 if (this.notificationWin.style.display == 'none')
@@ -6107,17 +6108,17 @@ App.prototype.showNotification = function(notifs, lsReadFlag) @@ -6107,17 +6108,17 @@ App.prototype.showNotification = function(notifs, lsReadFlag)
6107 markAllAsRead(); 6108 markAllAsRead();
6108 } 6109 }
6109 })); 6110 }));
6110 - 6111 +
6111 mxEvent.addListener(winClose, 'click', markAllAsRead); 6112 mxEvent.addListener(winClose, 'click', markAllAsRead);
6112 } 6113 }
6113 else 6114 else
6114 { 6115 {
6115 this.notificationBtn.style.display = ''; //In case it was hidden 6116 this.notificationBtn.style.display = ''; //In case it was hidden
6116 } 6117 }
6117 - 6118 +
6118 var newNotif = 0; 6119 var newNotif = 0;
6119 var notifListEl = document.getElementById('geNotifList'); 6120 var notifListEl = document.getElementById('geNotifList');
6120 - 6121 +
6121 if (notifListEl == null) 6122 if (notifListEl == null)
6122 { 6123 {
6123 return; //This shouldn't happen and no meaning of continuing 6124 return; //This shouldn't happen and no meaning of continuing
@@ -6125,7 +6126,7 @@ App.prototype.showNotification = function(notifs, lsReadFlag) @@ -6125,7 +6126,7 @@ App.prototype.showNotification = function(notifs, lsReadFlag)
6125 else 6126 else
6126 { 6127 {
6127 notifListEl.innerHTML = '<div class="line"></div>'; 6128 notifListEl.innerHTML = '<div class="line"></div>';
6128 - 6129 +
6129 for (var i = 0; i < notifs.length; i++) 6130 for (var i = 0; i < notifs.length; i++)
6130 { 6131 {
6131 (function(editorUi, notif) 6132 (function(editorUi, notif)
@@ -6134,19 +6135,19 @@ App.prototype.showNotification = function(notifs, lsReadFlag) @@ -6134,19 +6135,19 @@ App.prototype.showNotification = function(notifs, lsReadFlag)
6134 { 6135 {
6135 newNotif++; 6136 newNotif++;
6136 } 6137 }
6137 - 6138 +
6138 var notifEl = document.createElement('div'); 6139 var notifEl = document.createElement('div');
6139 notifEl.className = 'notification'; 6140 notifEl.className = 'notification';
6140 var ts = new Date(notif.timestamp); 6141 var ts = new Date(notif.timestamp);
6141 var str = editorUi.timeSince(ts); 6142 var str = editorUi.timeSince(ts);
6142 - 6143 +
6143 if (str == null) 6144 if (str == null)
6144 { 6145 {
6145 str = mxResources.get('lessThanAMinute'); 6146 str = mxResources.get('lessThanAMinute');
6146 } 6147 }
6147 -  
6148 - notifEl.innerHTML = '<div class="circle' + (notif.isNew? ' active' : '') + '"></div><span class="time">' +  
6149 - mxUtils.htmlEntities(mxResources.get('timeAgo', [str], '{1} ago')) + '</span>' + 6148 +
  6149 + notifEl.innerHTML = '<div class="circle' + (notif.isNew? ' active' : '') + '"></div><span class="time">' +
  6150 + mxUtils.htmlEntities(mxResources.get('timeAgo', [str], '{1} ago')) + '</span>' +
6150 '<p>' + mxUtils.htmlEntities(notif.content) + '</p>'; 6151 '<p>' + mxUtils.htmlEntities(notif.content) + '</p>';
6151 if (notif.link) 6152 if (notif.link)
6152 { 6153 {
@@ -6155,18 +6156,18 @@ App.prototype.showNotification = function(notifs, lsReadFlag) @@ -6155,18 +6156,18 @@ App.prototype.showNotification = function(notifs, lsReadFlag)
6155 window.open(notif.link, 'notifWin'); 6156 window.open(notif.link, 'notifWin');
6156 }); 6157 });
6157 } 6158 }
6158 - 6159 +
6159 notifListEl.appendChild(notifEl); 6160 notifListEl.appendChild(notifEl);
6160 })(this, notifs[i]); 6161 })(this, notifs[i]);
6161 } 6162 }
6162 } 6163 }
6163 - 6164 +
6164 shouldAnimate(newNotif); 6165 shouldAnimate(newNotif);
6165 }; 6166 };
6166 6167
6167 /** 6168 /**
6168 * Translates this point by the given vector. 6169 * Translates this point by the given vector.
6169 - * 6170 + *
6170 * @param {number} dx X-coordinate of the translation. 6171 * @param {number} dx X-coordinate of the translation.
6171 * @param {number} dy Y-coordinate of the translation. 6172 * @param {number} dy Y-coordinate of the translation.
6172 */ 6173 */
@@ -6176,12 +6177,12 @@ App.prototype.save = function(name, done) @@ -6176,12 +6177,12 @@ App.prototype.save = function(name, done)
6176 if (file != null && this.spinner.spin(document.body, mxResources.get('saving'))) 6177 if (file != null && this.spinner.spin(document.body, mxResources.get('saving')))
6177 { 6178 {
6178 this.editor.setStatus(''); 6179 this.editor.setStatus('');
6179 - 6180 +
6180 if (this.editor.graph.isEditing()) 6181 if (this.editor.graph.isEditing())
6181 { 6182 {
6182 this.editor.graph.stopEditing(); 6183 this.editor.graph.stopEditing();
6183 } 6184 }
6184 - 6185 +
6185 var success = mxUtils.bind(this, function() 6186 var success = mxUtils.bind(this, function()
6186 { 6187 {
6187 file.handleFileSuccess(true); 6188 file.handleFileSuccess(true);
@@ -6191,7 +6192,7 @@ App.prototype.save = function(name, done) @@ -6191,7 +6192,7 @@ App.prototype.save = function(name, done)
6191 done(); 6192 done();
6192 } 6193 }
6193 }); 6194 });
6194 - 6195 +
6195 var error = mxUtils.bind(this, function(err) 6196 var error = mxUtils.bind(this, function(err)
6196 { 6197 {
6197 if (file.isModified()) 6198 if (file.isModified())
@@ -6201,10 +6202,10 @@ App.prototype.save = function(name, done) @@ -6201,10 +6202,10 @@ App.prototype.save = function(name, done)
6201 this.save(name, done); 6202 this.save(name, done);
6202 })); 6203 }));
6203 } 6204 }
6204 - 6205 +
6205 file.handleFileError(err, err == null || err.name != 'AbortError'); 6206 file.handleFileError(err, err == null || err.name != 'AbortError');
6206 }); 6207 });
6207 - 6208 +
6208 try 6209 try
6209 { 6210 {
6210 if (name == file.getTitle()) 6211 if (name == file.getTitle())
@@ -6234,23 +6235,23 @@ App.prototype.pickFolder = function(mode, fn, enabled, direct, force) @@ -6234,23 +6235,23 @@ App.prototype.pickFolder = function(mode, fn, enabled, direct, force)
6234 { 6235 {
6235 enabled = (enabled != null) ? enabled : true; 6236 enabled = (enabled != null) ? enabled : true;
6236 var resume = this.spinner.pause(); 6237 var resume = this.spinner.pause();
6237 - 6238 +
6238 if (enabled && mode == App.MODE_GOOGLE && this.drive != null) 6239 if (enabled && mode == App.MODE_GOOGLE && this.drive != null)
6239 { 6240 {
6240 // Shows a save dialog 6241 // Shows a save dialog
6241 this.drive.pickFolder(mxUtils.bind(this, function(evt) 6242 this.drive.pickFolder(mxUtils.bind(this, function(evt)
6242 { 6243 {
6243 resume(); 6244 resume();
6244 - 6245 +
6245 if (evt.action == google.picker.Action.PICKED) 6246 if (evt.action == google.picker.Action.PICKED)
6246 { 6247 {
6247 var folderId = null; 6248 var folderId = null;
6248 - 6249 +
6249 if (evt.docs != null && evt.docs.length > 0 && evt.docs[0].type == 'folder') 6250 if (evt.docs != null && evt.docs.length > 0 && evt.docs[0].type == 'folder')
6250 { 6251 {
6251 folderId = evt.docs[0].id; 6252 folderId = evt.docs[0].id;
6252 } 6253 }
6253 - 6254 +
6254 fn(folderId); 6255 fn(folderId);
6255 } 6256 }
6256 }), force); 6257 }), force);
@@ -6261,7 +6262,7 @@ App.prototype.pickFolder = function(mode, fn, enabled, direct, force) @@ -6261,7 +6262,7 @@ App.prototype.pickFolder = function(mode, fn, enabled, direct, force)
6261 { 6262 {
6262 var folderId = null; 6263 var folderId = null;
6263 resume(); 6264 resume();
6264 - 6265 +
6265 if (files != null && files.value != null && files.value.length > 0) 6266 if (files != null && files.value != null && files.value.length > 0)
6266 { 6267 {
6267 folderId = OneDriveFile.prototype.getIdOf(files.value[0]); 6268 folderId = OneDriveFile.prototype.getIdOf(files.value[0]);
@@ -6300,7 +6301,7 @@ App.prototype.pickFolder = function(mode, fn, enabled, direct, force) @@ -6300,7 +6301,7 @@ App.prototype.pickFolder = function(mode, fn, enabled, direct, force)
6300 }; 6301 };
6301 6302
6302 /** 6303 /**
6303 - * 6304 + *
6304 */ 6305 */
6305 App.prototype.exportFile = function(data, filename, mimeType, base64Encoded, mode, folderId) 6306 App.prototype.exportFile = function(data, filename, mimeType, base64Encoded, mode, folderId)
6306 { 6307 {
@@ -6330,12 +6331,12 @@ App.prototype.exportFile = function(data, filename, mimeType, base64Encoded, mod @@ -6330,12 +6331,12 @@ App.prototype.exportFile = function(data, filename, mimeType, base64Encoded, mod
6330 // "File exported. Click here to open folder." 6331 // "File exported. Click here to open folder."
6331 // this.editor.setStatus('<div class="geStatusMessage">' + 6332 // this.editor.setStatus('<div class="geStatusMessage">' +
6332 // mxResources.get('saved') + '</div>'); 6333 // mxResources.get('saved') + '</div>');
6333 -// 6334 +//
6334 // // Installs click handler for opening 6335 // // Installs click handler for opening
6335 // if (this.statusContainer != null) 6336 // if (this.statusContainer != null)
6336 // { 6337 // {
6337 // var links = this.statusContainer.getElementsByTagName('div'); 6338 // var links = this.statusContainer.getElementsByTagName('div');
6338 -// 6339 +//
6339 // if (links.length > 0) 6340 // if (links.length > 0)
6340 // { 6341 // {
6341 // links[0].style.cursor = 'pointer'; 6342 // links[0].style.cursor = 'pointer';
@@ -6349,7 +6350,7 @@ App.prototype.exportFile = function(data, filename, mimeType, base64Encoded, mod @@ -6349,7 +6350,7 @@ App.prototype.exportFile = function(data, filename, mimeType, base64Encoded, mod
6349 // })); 6350 // }));
6350 // } 6351 // }
6351 // } 6352 // }
6352 - 6353 +
6353 this.spinner.stop(); 6354 this.spinner.stop();
6354 }), mxUtils.bind(this, function(resp) 6355 }), mxUtils.bind(this, function(resp)
6355 { 6356 {
@@ -6425,7 +6426,7 @@ App.prototype.exportFile = function(data, filename, mimeType, base64Encoded, mod @@ -6425,7 +6426,7 @@ App.prototype.exportFile = function(data, filename, mimeType, base64Encoded, mod
6425 { 6426 {
6426 localStorage.setItem(filename, data); 6427 localStorage.setItem(filename, data);
6427 }); 6428 });
6428 - 6429 +
6429 if (localStorage.getItem(filename) == null) 6430 if (localStorage.getItem(filename) == null)
6430 { 6431 {
6431 fn(); 6432 fn();
@@ -6439,14 +6440,14 @@ App.prototype.exportFile = function(data, filename, mimeType, base64Encoded, mod @@ -6439,14 +6440,14 @@ App.prototype.exportFile = function(data, filename, mimeType, base64Encoded, mod
6439 6440
6440 /** 6441 /**
6441 * Translates this point by the given vector. 6442 * Translates this point by the given vector.
6442 - * 6443 + *
6443 * @param {number} dx X-coordinate of the translation. 6444 * @param {number} dx X-coordinate of the translation.
6444 * @param {number} dy Y-coordinate of the translation. 6445 * @param {number} dy Y-coordinate of the translation.
6445 */ 6446 */
6446 App.prototype.descriptorChanged = function() 6447 App.prototype.descriptorChanged = function()
6447 { 6448 {
6448 var file = this.getCurrentFile(); 6449 var file = this.getCurrentFile();
6449 - 6450 +
6450 if (file != null) 6451 if (file != null)
6451 { 6452 {
6452 if (this.fname != null) 6453 if (this.fname != null)
@@ -6457,23 +6458,23 @@ App.prototype.descriptorChanged = function() @@ -6457,23 +6458,23 @@ App.prototype.descriptorChanged = function()
6457 mxUtils.write(this.fname, filename); 6458 mxUtils.write(this.fname, filename);
6458 this.fname.setAttribute('title', filename + ' - ' + mxResources.get('rename')); 6459 this.fname.setAttribute('title', filename + ' - ' + mxResources.get('rename'));
6459 } 6460 }
6460 - 6461 +
6461 var graph = this.editor.graph; 6462 var graph = this.editor.graph;
6462 var editable = file.isEditable() && !file.invalidChecksum; 6463 var editable = file.isEditable() && !file.invalidChecksum;
6463 - 6464 +
6464 if (graph.isEnabled() && !editable) 6465 if (graph.isEnabled() && !editable)
6465 { 6466 {
6466 graph.reset(); 6467 graph.reset();
6467 } 6468 }
6468 - 6469 +
6469 graph.setEnabled(editable); 6470 graph.setEnabled(editable);
6470 - 6471 +
6471 // Ignores title and hash for revisions 6472 // Ignores title and hash for revisions
6472 if (urlParams['rev'] == null) 6473 if (urlParams['rev'] == null)
6473 { 6474 {
6474 this.updateDocumentTitle(); 6475 this.updateDocumentTitle();
6475 var newHash = file.getHash(); 6476 var newHash = file.getHash();
6476 - 6477 +
6477 if (newHash.length > 0) 6478 if (newHash.length > 0)
6478 { 6479 {
6479 window.location.hash = newHash; 6480 window.location.hash = newHash;
@@ -6484,9 +6485,9 @@ App.prototype.descriptorChanged = function() @@ -6484,9 +6485,9 @@ App.prototype.descriptorChanged = function()
6484 } 6485 }
6485 } 6486 }
6486 } 6487 }
6487 - 6488 +
6488 this.updateUi(); 6489 this.updateUi();
6489 - 6490 +
6490 // Refresh if editable state has changed 6491 // Refresh if editable state has changed
6491 if (this.format != null && (file == null || 6492 if (this.format != null && (file == null ||
6492 this.fileEditable != file.isEditable()) && 6493 this.fileEditable != file.isEditable()) &&
@@ -6495,7 +6496,7 @@ App.prototype.descriptorChanged = function() @@ -6495,7 +6496,7 @@ App.prototype.descriptorChanged = function()
6495 this.format.refresh(); 6496 this.format.refresh();
6496 this.fileEditable = (file != null) ? file.isEditable() : null; 6497 this.fileEditable = (file != null) ? file.isEditable() : null;
6497 } 6498 }
6498 - 6499 +
6499 this.fireEvent(new mxEventObject('fileDescriptorChanged', 'file', file)); 6500 this.fireEvent(new mxEventObject('fileDescriptorChanged', 'file', file));
6500 }; 6501 };
6501 6502
@@ -6505,7 +6506,7 @@ App.prototype.descriptorChanged = function() @@ -6505,7 +6506,7 @@ App.prototype.descriptorChanged = function()
6505 App.prototype.showAuthDialog = function(peer, showRememberOption, fn, closeFn) 6506 App.prototype.showAuthDialog = function(peer, showRememberOption, fn, closeFn)
6506 { 6507 {
6507 var resume = this.spinner.pause(); 6508 var resume = this.spinner.pause();
6508 - 6509 +
6509 this.showDialog(new AuthDialog(this, peer, showRememberOption, mxUtils.bind(this, function(remember) 6510 this.showDialog(new AuthDialog(this, peer, showRememberOption, mxUtils.bind(this, function(remember)
6510 { 6511 {
6511 try 6512 try
@@ -6529,7 +6530,7 @@ App.prototype.showAuthDialog = function(peer, showRememberOption, fn, closeFn) @@ -6529,7 +6530,7 @@ App.prototype.showAuthDialog = function(peer, showRememberOption, fn, closeFn)
6529 { 6530 {
6530 closeFn(cancel); 6531 closeFn(cancel);
6531 } 6532 }
6532 - 6533 +
6533 if (cancel && this.getCurrentFile() == null && this.dialog == null) 6534 if (cancel && this.getCurrentFile() == null && this.dialog == null)
6534 { 6535 {
6535 this.showSplash(); 6536 this.showSplash();
@@ -6545,32 +6546,32 @@ App.prototype.showAuthDialog = function(peer, showRememberOption, fn, closeFn) @@ -6545,32 +6546,32 @@ App.prototype.showAuthDialog = function(peer, showRememberOption, fn, closeFn)
6545 App.prototype.convertFile = function(url, filename, mimeType, extension, success, error, executeRequest, headers) 6546 App.prototype.convertFile = function(url, filename, mimeType, extension, success, error, executeRequest, headers)
6546 { 6547 {
6547 var name = filename; 6548 var name = filename;
6548 - 6549 +
6549 // SVG file extensions are valid and needed for image import 6550 // SVG file extensions are valid and needed for image import
6550 if (!/\.svg$/i.test(name)) 6551 if (!/\.svg$/i.test(name))
6551 { 6552 {
6552 name = name.substring(0, filename.lastIndexOf('.')) + extension; 6553 name = name.substring(0, filename.lastIndexOf('.')) + extension;
6553 } 6554 }
6554 - 6555 +
6555 var gitHubUrl = false; 6556 var gitHubUrl = false;
6556 - 6557 +
6557 if (this.gitHub != null && url.substring(0, this.gitHub.baseUrl.length) == this.gitHub.baseUrl) 6558 if (this.gitHub != null && url.substring(0, this.gitHub.baseUrl.length) == this.gitHub.baseUrl)
6558 { 6559 {
6559 gitHubUrl = true; 6560 gitHubUrl = true;
6560 } 6561 }
6561 - 6562 +
6562 // Workaround for wrong binary response with VSD(X) & VDX files 6563 // Workaround for wrong binary response with VSD(X) & VDX files
6563 if (/\.v(dx|sdx?)$/i.test(filename) && Graph.fileSupport && new XMLHttpRequest().upload && 6564 if (/\.v(dx|sdx?)$/i.test(filename) && Graph.fileSupport && new XMLHttpRequest().upload &&
6564 typeof new XMLHttpRequest().responseType === 'string') 6565 typeof new XMLHttpRequest().responseType === 'string')
6565 { 6566 {
6566 var req = new XMLHttpRequest(); 6567 var req = new XMLHttpRequest();
6567 req.open('GET', url, true); 6568 req.open('GET', url, true);
6568 - 6569 +
6569 if (!gitHubUrl) 6570 if (!gitHubUrl)
6570 { 6571 {
6571 req.responseType = 'blob'; 6572 req.responseType = 'blob';
6572 } 6573 }
6573 - 6574 +
6574 if (headers) 6575 if (headers)
6575 { 6576 {
6576 for (var key in headers) 6577 for (var key in headers)
@@ -6578,13 +6579,13 @@ App.prototype.convertFile = function(url, filename, mimeType, extension, success @@ -6578,13 +6579,13 @@ App.prototype.convertFile = function(url, filename, mimeType, extension, success
6578 req.setRequestHeader(key, headers[key]); 6579 req.setRequestHeader(key, headers[key]);
6579 } 6580 }
6580 } 6581 }
6581 - 6582 +
6582 req.onload = mxUtils.bind(this, function() 6583 req.onload = mxUtils.bind(this, function()
6583 { 6584 {
6584 if (req.status >= 200 && req.status <= 299) 6585 if (req.status >= 200 && req.status <= 299)
6585 { 6586 {
6586 var blob = null; 6587 var blob = null;
6587 - 6588 +
6588 if (gitHubUrl) 6589 if (gitHubUrl)
6589 { 6590 {
6590 var file = JSON.parse(req.responseText); 6591 var file = JSON.parse(req.responseText);
@@ -6594,7 +6595,7 @@ App.prototype.convertFile = function(url, filename, mimeType, extension, success @@ -6594,7 +6595,7 @@ App.prototype.convertFile = function(url, filename, mimeType, extension, success
6594 { 6595 {
6595 blob = new Blob([req.response], {type: 'application/octet-stream'}); 6596 blob = new Blob([req.response], {type: 'application/octet-stream'});
6596 } 6597 }
6597 - 6598 +
6598 this.importVisio(blob, mxUtils.bind(this, function(xml) 6599 this.importVisio(blob, mxUtils.bind(this, function(xml)
6599 { 6600 {
6600 success(new LocalFile(this, xml, name, true)); 6601 success(new LocalFile(this, xml, name, true));
@@ -6618,7 +6619,7 @@ App.prototype.convertFile = function(url, filename, mimeType, extension, success @@ -6618,7 +6619,7 @@ App.prototype.convertFile = function(url, filename, mimeType, extension, success
6618 if (/\.pdf$/i.test(filename)) 6619 if (/\.pdf$/i.test(filename))
6619 { 6620 {
6620 var temp = Editor.extractGraphModelFromPdf(data); 6621 var temp = Editor.extractGraphModelFromPdf(data);
6621 - 6622 +
6622 if (temp != null && temp.length > 0) 6623 if (temp != null && temp.length > 0)
6623 { 6624 {
6624 success(new LocalFile(this, temp, name, true)); 6625 success(new LocalFile(this, temp, name, true));
@@ -6627,7 +6628,7 @@ App.prototype.convertFile = function(url, filename, mimeType, extension, success @@ -6627,7 +6628,7 @@ App.prototype.convertFile = function(url, filename, mimeType, extension, success
6627 else if (/\.png$/i.test(filename)) 6628 else if (/\.png$/i.test(filename))
6628 { 6629 {
6629 var temp = this.extractGraphModelFromPng(data); 6630 var temp = this.extractGraphModelFromPng(data);
6630 - 6631 +
6631 if (temp != null) 6632 if (temp != null)
6632 { 6633 {
6633 success(new LocalFile(this, temp, name, true)); 6634 success(new LocalFile(this, temp, name, true));
@@ -6671,7 +6672,7 @@ App.prototype.convertFile = function(url, filename, mimeType, extension, success @@ -6671,7 +6672,7 @@ App.prototype.convertFile = function(url, filename, mimeType, extension, success
6671 var binary = /\.png$/i.test(filename) || /\.jpe?g$/i.test(filename) || 6672 var binary = /\.png$/i.test(filename) || /\.jpe?g$/i.test(filename) ||
6672 /\.pdf$/i.test(filename) || (mimeType != null && 6673 /\.pdf$/i.test(filename) || (mimeType != null &&
6673 mimeType.substring(0, 6) == 'image/'); 6674 mimeType.substring(0, 6) == 'image/');
6674 - 6675 +
6675 // NOTE: Cannot force non-binary request via loadUrl so needs separate 6676 // NOTE: Cannot force non-binary request via loadUrl so needs separate
6676 // code as decoding twice on content with binary data did not work 6677 // code as decoding twice on content with binary data did not work
6677 if (gitHubUrl) 6678 if (gitHubUrl)
@@ -6684,16 +6685,16 @@ App.prototype.convertFile = function(url, filename, mimeType, extension, success @@ -6684,16 +6685,16 @@ App.prototype.convertFile = function(url, filename, mimeType, extension, success
6684 { 6685 {
6685 var file = JSON.parse(req.getText()); 6686 var file = JSON.parse(req.getText());
6686 var data = file.content; 6687 var data = file.content;
6687 - 6688 +
6688 if (file.encoding === 'base64') 6689 if (file.encoding === 'base64')
6689 { 6690 {
6690 if (/\.png$/i.test(filename)) 6691 if (/\.png$/i.test(filename))
6691 { 6692 {
6692 - data = 'data:image/png;base64,' + data; 6693 + data = 'data:image/png;base64,' + data;
6693 } 6694 }
6694 else if (/\.pdf$/i.test(filename)) 6695 else if (/\.pdf$/i.test(filename))
6695 { 6696 {
6696 - data = 'data:application/pdf;base64,' + data; 6697 + data = 'data:application/pdf;base64,' + data;
6697 } 6698 }
6698 else 6699 else
6699 { 6700 {
@@ -6701,7 +6702,7 @@ App.prototype.convertFile = function(url, filename, mimeType, extension, success @@ -6701,7 +6702,7 @@ App.prototype.convertFile = function(url, filename, mimeType, extension, success
6701 data = (window.atob && !mxClient.IS_IE && !mxClient.IS_IE11) ? atob(data) : Base64.decode(data); 6702 data = (window.atob && !mxClient.IS_IE && !mxClient.IS_IE11) ? atob(data) : Base64.decode(data);
6702 } 6703 }
6703 } 6704 }
6704 - 6705 +
6705 handleData(data); 6706 handleData(data);
6706 } 6707 }
6707 } 6708 }
@@ -6736,7 +6737,7 @@ App.prototype.convertFile = function(url, filename, mimeType, extension, success @@ -6736,7 +6737,7 @@ App.prototype.convertFile = function(url, filename, mimeType, extension, success
6736 6737
6737 /** 6738 /**
6738 * Adds the listener for automatically saving the diagram for local changes. 6739 * Adds the listener for automatically saving the diagram for local changes.
6739 - */ 6740 + */
6740 App.prototype.updateHeader = function() 6741 App.prototype.updateHeader = function()
6741 { 6742 {
6742 if (this.menubar != null) 6743 if (this.menubar != null)
@@ -6749,40 +6750,40 @@ App.prototype.updateHeader = function() @@ -6749,40 +6750,40 @@ App.prototype.updateHeader = function()
6749 this.appIcon.style.margin = '14px 0px 8px 16px'; 6750 this.appIcon.style.margin = '14px 0px 8px 16px';
6750 this.appIcon.style.opacity = '0.85'; 6751 this.appIcon.style.opacity = '0.85';
6751 this.appIcon.style.borderRadius = '3px'; 6752 this.appIcon.style.borderRadius = '3px';
6752 - 6753 +
6753 if (uiTheme != 'dark') 6754 if (uiTheme != 'dark')
6754 { 6755 {
6755 this.appIcon.style.backgroundColor = '#f08705'; 6756 this.appIcon.style.backgroundColor = '#f08705';
6756 } 6757 }
6757 - 6758 +
6758 mxEvent.disableContextMenu(this.appIcon); 6759 mxEvent.disableContextMenu(this.appIcon);
6759 - 6760 +
6760 mxEvent.addListener(this.appIcon, 'click', mxUtils.bind(this, function(evt) 6761 mxEvent.addListener(this.appIcon, 'click', mxUtils.bind(this, function(evt)
6761 { 6762 {
6762 this.appIconClicked(evt); 6763 this.appIconClicked(evt);
6763 })); 6764 }));
6764 - 6765 +
6765 // LATER: Use Alpha image loader in IE6 6766 // LATER: Use Alpha image loader in IE6
6766 // NOTE: This uses the diagram bit of the old logo as it looks better in this case 6767 // NOTE: This uses the diagram bit of the old logo as it looks better in this case
6767 //this.appIcon.style.filter = 'progid:DXImageTransform.Microsoft.AlphaImageLoader(src=' + IMAGE_PATH + '/logo-white.png,sizingMethod=\'scale\')'; 6768 //this.appIcon.style.filter = 'progid:DXImageTransform.Microsoft.AlphaImageLoader(src=' + IMAGE_PATH + '/logo-white.png,sizingMethod=\'scale\')';
6768 var logo = (!mxClient.IS_SVG) ? 'url(\'' + IMAGE_PATH + '/logo-white.png\')' : 6769 var logo = (!mxClient.IS_SVG) ? 'url(\'' + IMAGE_PATH + '/logo-white.png\')' :
6769 ((uiTheme == 'dark') ? 'url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcKICAgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIgogICB4bWxuczpjYz0iaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbnMjIgogICB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiCiAgIHhtbG5zOnN2Zz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciCiAgIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIKICAgeG1sOnNwYWNlPSJwcmVzZXJ2ZSIKICAgZW5hYmxlLWJhY2tncm91bmQ9Im5ldyAwIDAgMzA2LjE4NSAxMjAuMjk2IgogICB2aWV3Qm94PSIyNCAyNiA2OCA2OCIKICAgeT0iMHB4IgogICB4PSIwcHgiCiAgIHZlcnNpb249IjEuMSI+CiAgIAkgPGc+PGxpbmUKICAgICAgIHkyPSI3Mi4zOTQiCiAgICAgICB4Mj0iNDEuMDYxIgogICAgICAgeTE9IjQzLjM4NCIKICAgICAgIHgxPSI1OC4wNjkiCiAgICAgICBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiCiAgICAgICBzdHJva2Utd2lkdGg9IjMuNTUyOCIKICAgICAgIHN0cm9rZT0iI0ZGRkZGRiIKICAgICAgIGZpbGw9Im5vbmUiIC8+PGxpbmUKICAgICAgIHkyPSI3Mi4zOTQiCiAgICAgICB4Mj0iNzUuMDc2IgogICAgICAgeTE9IjQzLjM4NCIKICAgICAgIHgxPSI1OC4wNjgiCiAgICAgICBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiCiAgICAgICBzdHJva2Utd2lkdGg9IjMuNTAwOCIKICAgICAgIHN0cm9rZT0iI0ZGRkZGRiIKICAgICAgIGZpbGw9Im5vbmUiIC8+PGc+PHBhdGgKICAgICAgICAgZD0iTTUyLjc3Myw3Ny4wODRjMCwxLjk1NC0xLjU5OSwzLjU1My0zLjU1MywzLjU1M0gzNi45OTljLTEuOTU0LDAtMy41NTMtMS41OTktMy41NTMtMy41NTN2LTkuMzc5ICAgIGMwLTEuOTU0LDEuNTk5LTMuNTUzLDMuNTUzLTMuNTUzaDEyLjIyMmMxLjk1NCwwLDMuNTUzLDEuNTk5LDMuNTUzLDMuNTUzVjc3LjA4NHoiCiAgICAgICAgIGZpbGw9IiNGRkZGRkYiIC8+PC9nPjxnCiAgICAgICBpZD0iZzM0MTkiPjxwYXRoCiAgICAgICAgIGQ9Ik02Ny43NjIsNDguMDc0YzAsMS45NTQtMS41OTksMy41NTMtMy41NTMsMy41NTNINTEuOTg4Yy0xLjk1NCwwLTMuNTUzLTEuNTk5LTMuNTUzLTMuNTUzdi05LjM3OSAgICBjMC0xLjk1NCwxLjU5OS0zLjU1MywzLjU1My0zLjU1M0g2NC4yMWMxLjk1NCwwLDMuNTUzLDEuNTk5LDMuNTUzLDMuNTUzVjQ4LjA3NHoiCiAgICAgICAgIGZpbGw9IiNGRkZGRkYiIC8+PC9nPjxnPjxwYXRoCiAgICAgICAgIGQ9Ik04Mi43NTIsNzcuMDg0YzAsMS45NTQtMS41OTksMy41NTMtMy41NTMsMy41NTNINjYuOTc3Yy0xLjk1NCwwLTMuNTUzLTEuNTk5LTMuNTUzLTMuNTUzdi05LjM3OSAgICBjMC0xLjk1NCwxLjU5OS0zLjU1MywzLjU1My0zLjU1M2gxMi4yMjJjMS45NTQsMCwzLjU1MywxLjU5OSwzLjU1MywzLjU1M1Y3Ny4wODR6IgogICAgICAgICBmaWxsPSIjRkZGRkZGIiAvPjwvZz48L2c+PC9zdmc+)' : 6770 ((uiTheme == 'dark') ? 'url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcKICAgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIgogICB4bWxuczpjYz0iaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbnMjIgogICB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiCiAgIHhtbG5zOnN2Zz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciCiAgIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIKICAgeG1sOnNwYWNlPSJwcmVzZXJ2ZSIKICAgZW5hYmxlLWJhY2tncm91bmQ9Im5ldyAwIDAgMzA2LjE4NSAxMjAuMjk2IgogICB2aWV3Qm94PSIyNCAyNiA2OCA2OCIKICAgeT0iMHB4IgogICB4PSIwcHgiCiAgIHZlcnNpb249IjEuMSI+CiAgIAkgPGc+PGxpbmUKICAgICAgIHkyPSI3Mi4zOTQiCiAgICAgICB4Mj0iNDEuMDYxIgogICAgICAgeTE9IjQzLjM4NCIKICAgICAgIHgxPSI1OC4wNjkiCiAgICAgICBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiCiAgICAgICBzdHJva2Utd2lkdGg9IjMuNTUyOCIKICAgICAgIHN0cm9rZT0iI0ZGRkZGRiIKICAgICAgIGZpbGw9Im5vbmUiIC8+PGxpbmUKICAgICAgIHkyPSI3Mi4zOTQiCiAgICAgICB4Mj0iNzUuMDc2IgogICAgICAgeTE9IjQzLjM4NCIKICAgICAgIHgxPSI1OC4wNjgiCiAgICAgICBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiCiAgICAgICBzdHJva2Utd2lkdGg9IjMuNTAwOCIKICAgICAgIHN0cm9rZT0iI0ZGRkZGRiIKICAgICAgIGZpbGw9Im5vbmUiIC8+PGc+PHBhdGgKICAgICAgICAgZD0iTTUyLjc3Myw3Ny4wODRjMCwxLjk1NC0xLjU5OSwzLjU1My0zLjU1MywzLjU1M0gzNi45OTljLTEuOTU0LDAtMy41NTMtMS41OTktMy41NTMtMy41NTN2LTkuMzc5ICAgIGMwLTEuOTU0LDEuNTk5LTMuNTUzLDMuNTUzLTMuNTUzaDEyLjIyMmMxLjk1NCwwLDMuNTUzLDEuNTk5LDMuNTUzLDMuNTUzVjc3LjA4NHoiCiAgICAgICAgIGZpbGw9IiNGRkZGRkYiIC8+PC9nPjxnCiAgICAgICBpZD0iZzM0MTkiPjxwYXRoCiAgICAgICAgIGQ9Ik02Ny43NjIsNDguMDc0YzAsMS45NTQtMS41OTksMy41NTMtMy41NTMsMy41NTNINTEuOTg4Yy0xLjk1NCwwLTMuNTUzLTEuNTk5LTMuNTUzLTMuNTUzdi05LjM3OSAgICBjMC0xLjk1NCwxLjU5OS0zLjU1MywzLjU1My0zLjU1M0g2NC4yMWMxLjk1NCwwLDMuNTUzLDEuNTk5LDMuNTUzLDMuNTUzVjQ4LjA3NHoiCiAgICAgICAgIGZpbGw9IiNGRkZGRkYiIC8+PC9nPjxnPjxwYXRoCiAgICAgICAgIGQ9Ik04Mi43NTIsNzcuMDg0YzAsMS45NTQtMS41OTksMy41NTMtMy41NTMsMy41NTNINjYuOTc3Yy0xLjk1NCwwLTMuNTUzLTEuNTk5LTMuNTUzLTMuNTUzdi05LjM3OSAgICBjMC0xLjk1NCwxLjU5OS0zLjU1MywzLjU1My0zLjU1M2gxMi4yMjJjMS45NTQsMCwzLjU1MywxLjU5OSwzLjU1MywzLjU1M1Y3Ny4wODR6IgogICAgICAgICBmaWxsPSIjRkZGRkZGIiAvPjwvZz48L2c+PC9zdmc+)' :
6770 'url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPHN2ZyB2ZXJzaW9uPSIxLjEiIGlkPSJFYmVuZV8xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB4PSIwcHgiIHk9IjBweCIKCSB2aWV3Qm94PSIwIDAgMjI1IDIyNSIgc3R5bGU9ImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAgMjI1IDIyNTsiIHhtbDpzcGFjZT0icHJlc2VydmUiPgo8c3R5bGUgdHlwZT0idGV4dC9jc3MiPgoJLnN0MXtmaWxsOiNERjZDMEM7fQoJLnN0MntmaWxsOiNGRkZGRkY7fQo8L3N0eWxlPgo8cGF0aCBjbGFzcz0ic3QxIiBkPSJNMjI1LDIxNS40YzAsNS4zLTQuMyw5LjYtOS41LDkuNmwwLDBINzcuMWwtNDQuOC00NS41TDYwLjIsMTM0bDgyLjctMTAyLjdsODIuMSw4NC41VjIxNS40eiIvPgo8cGF0aCBjbGFzcz0ic3QyIiBkPSJNMTg0LjYsMTI1LjhoLTIzLjdsLTI1LTQyLjdjNS43LTEuMiw5LjgtNi4yLDkuNy0xMlYzOWMwLTYuOC01LjQtMTIuMy0xMi4yLTEyLjNoLTAuMUg5MS42CgljLTYuOCwwLTEyLjMsNS40LTEyLjMsMTIuMlYzOXYzMi4xYzAsNS44LDQsMTAuOCw5LjcsMTJsLTI1LDQyLjdINDAuNGMtNi44LDAtMTIuMyw1LjQtMTIuMywxMi4ydjAuMXYzMi4xCgljMCw2LjgsNS40LDEyLjMsMTIuMiwxMi4zaDAuMWg0MS43YzYuOCwwLDEyLjMtNS40LDEyLjMtMTIuMnYtMC4xdi0zMi4xYzAtNi44LTUuNC0xMi4zLTEyLjItMTIuM2gtMC4xaC00bDI0LjgtNDIuNGgxOS4zCglsMjQuOSw0Mi40SDE0M2MtNi44LDAtMTIuMyw1LjQtMTIuMywxMi4ydjAuMXYzMi4xYzAsNi44LDUuNCwxMi4zLDEyLjIsMTIuM2gwLjFoNDEuN2M2LjgsMCwxMi4zLTUuNCwxMi4zLTEyLjJ2LTAuMXYtMzIuMQoJYzAtNi44LTUuNC0xMi4zLTEyLjItMTIuM0MxODQuNywxMjUuOCwxODQuNywxMjUuOCwxODQuNiwxMjUuOHoiLz4KPC9zdmc+Cg==)'); 6771 'url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPHN2ZyB2ZXJzaW9uPSIxLjEiIGlkPSJFYmVuZV8xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB4PSIwcHgiIHk9IjBweCIKCSB2aWV3Qm94PSIwIDAgMjI1IDIyNSIgc3R5bGU9ImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAgMjI1IDIyNTsiIHhtbDpzcGFjZT0icHJlc2VydmUiPgo8c3R5bGUgdHlwZT0idGV4dC9jc3MiPgoJLnN0MXtmaWxsOiNERjZDMEM7fQoJLnN0MntmaWxsOiNGRkZGRkY7fQo8L3N0eWxlPgo8cGF0aCBjbGFzcz0ic3QxIiBkPSJNMjI1LDIxNS40YzAsNS4zLTQuMyw5LjYtOS41LDkuNmwwLDBINzcuMWwtNDQuOC00NS41TDYwLjIsMTM0bDgyLjctMTAyLjdsODIuMSw4NC41VjIxNS40eiIvPgo8cGF0aCBjbGFzcz0ic3QyIiBkPSJNMTg0LjYsMTI1LjhoLTIzLjdsLTI1LTQyLjdjNS43LTEuMiw5LjgtNi4yLDkuNy0xMlYzOWMwLTYuOC01LjQtMTIuMy0xMi4yLTEyLjNoLTAuMUg5MS42CgljLTYuOCwwLTEyLjMsNS40LTEyLjMsMTIuMlYzOXYzMi4xYzAsNS44LDQsMTAuOCw5LjcsMTJsLTI1LDQyLjdINDAuNGMtNi44LDAtMTIuMyw1LjQtMTIuMywxMi4ydjAuMXYzMi4xCgljMCw2LjgsNS40LDEyLjMsMTIuMiwxMi4zaDAuMWg0MS43YzYuOCwwLDEyLjMtNS40LDEyLjMtMTIuMnYtMC4xdi0zMi4xYzAtNi44LTUuNC0xMi4zLTEyLjItMTIuM2gtMC4xaC00bDI0LjgtNDIuNGgxOS4zCglsMjQuOSw0Mi40SDE0M2MtNi44LDAtMTIuMyw1LjQtMTIuMywxMi4ydjAuMXYzMi4xYzAsNi44LDUuNCwxMi4zLDEyLjIsMTIuM2gwLjFoNDEuN2M2LjgsMCwxMi4zLTUuNCwxMi4zLTEyLjJ2LTAuMXYtMzIuMQoJYzAtNi44LTUuNC0xMi4zLTEyLjItMTIuM0MxODQuNywxMjUuOCwxODQuNywxMjUuOCwxODQuNiwxMjUuOHoiLz4KPC9zdmc+Cg==)');
6771 - this.appIcon.style.backgroundImage = logo; 6772 + this.appIcon.style.backgroundImage = logo;
6772 this.appIcon.style.backgroundPosition = 'center center'; 6773 this.appIcon.style.backgroundPosition = 'center center';
6773 this.appIcon.style.backgroundSize = '100% 100%'; 6774 this.appIcon.style.backgroundSize = '100% 100%';
6774 this.appIcon.style.backgroundRepeat = 'no-repeat'; 6775 this.appIcon.style.backgroundRepeat = 'no-repeat';
6775 - 6776 +
6776 mxUtils.setPrefixedStyle(this.appIcon.style, 'transition', 'all 125ms linear'); 6777 mxUtils.setPrefixedStyle(this.appIcon.style, 'transition', 'all 125ms linear');
6777 - 6778 +
6778 mxEvent.addListener(this.appIcon, 'mouseover', mxUtils.bind(this, function() 6779 mxEvent.addListener(this.appIcon, 'mouseover', mxUtils.bind(this, function()
6779 { 6780 {
6780 var file = this.getCurrentFile(); 6781 var file = this.getCurrentFile();
6781 - 6782 +
6782 if (file != null) 6783 if (file != null)
6783 { 6784 {
6784 var mode = file.getMode(); 6785 var mode = file.getMode();
6785 - 6786 +
6786 if (mode == App.MODE_GOOGLE) 6787 if (mode == App.MODE_GOOGLE)
6787 { 6788 {
6788 this.appIcon.style.backgroundImage = 'url(' + IMAGE_PATH + '/google-drive-logo-white.svg)'; 6789 this.appIcon.style.backgroundImage = 'url(' + IMAGE_PATH + '/google-drive-logo-white.svg)';
@@ -6815,18 +6816,18 @@ App.prototype.updateHeader = function() @@ -6815,18 +6816,18 @@ App.prototype.updateHeader = function()
6815 } 6816 }
6816 } 6817 }
6817 })); 6818 }));
6818 - 6819 +
6819 mxEvent.addListener(this.appIcon, 'mouseout', mxUtils.bind(this, function() 6820 mxEvent.addListener(this.appIcon, 'mouseout', mxUtils.bind(this, function()
6820 { 6821 {
6821 this.appIcon.style.backgroundImage = logo; 6822 this.appIcon.style.backgroundImage = logo;
6822 this.appIcon.style.backgroundSize = '90% 90%'; 6823 this.appIcon.style.backgroundSize = '90% 90%';
6823 })); 6824 }));
6824 - 6825 +
6825 if (urlParams['embed'] != '1') 6826 if (urlParams['embed'] != '1')
6826 { 6827 {
6827 this.menubarContainer.appendChild(this.appIcon); 6828 this.menubarContainer.appendChild(this.appIcon);
6828 } 6829 }
6829 - 6830 +
6830 this.fnameWrapper = document.createElement('div'); 6831 this.fnameWrapper = document.createElement('div');
6831 this.fnameWrapper.style.position = 'absolute'; 6832 this.fnameWrapper.style.position = 'absolute';
6832 this.fnameWrapper.style.right = '120px'; 6833 this.fnameWrapper.style.right = '120px';
@@ -6836,7 +6837,7 @@ App.prototype.updateHeader = function() @@ -6836,7 +6837,7 @@ App.prototype.updateHeader = function()
6836 this.fnameWrapper.style.display = 'none'; 6837 this.fnameWrapper.style.display = 'none';
6837 this.fnameWrapper.style.overflow = 'hidden'; 6838 this.fnameWrapper.style.overflow = 'hidden';
6838 this.fnameWrapper.style.textOverflow = 'ellipsis'; 6839 this.fnameWrapper.style.textOverflow = 'ellipsis';
6839 - 6840 +
6840 this.fname = document.createElement('a'); 6841 this.fname = document.createElement('a');
6841 this.fname.setAttribute('title', mxResources.get('rename')); 6842 this.fname.setAttribute('title', mxResources.get('rename'));
6842 this.fname.className = 'geItem'; 6843 this.fname.className = 'geItem';
@@ -6844,18 +6845,18 @@ App.prototype.updateHeader = function() @@ -6844,18 +6845,18 @@ App.prototype.updateHeader = function()
6844 this.fname.style.display = 'inline'; 6845 this.fname.style.display = 'inline';
6845 this.fname.style.fontSize = '18px'; 6846 this.fname.style.fontSize = '18px';
6846 this.fname.style.whiteSpace = 'nowrap'; 6847 this.fname.style.whiteSpace = 'nowrap';
6847 - 6848 +
6848 // Prevents focus 6849 // Prevents focus
6849 mxEvent.addListener(this.fname, (mxClient.IS_POINTER) ? 'pointerdown' : 'mousedown', 6850 mxEvent.addListener(this.fname, (mxClient.IS_POINTER) ? 'pointerdown' : 'mousedown',
6850 mxUtils.bind(this, function(evt) 6851 mxUtils.bind(this, function(evt)
6851 { 6852 {
6852 evt.preventDefault(); 6853 evt.preventDefault();
6853 })); 6854 }));
6854 - 6855 +
6855 mxEvent.addListener(this.fname, 'click', mxUtils.bind(this, function(evt) 6856 mxEvent.addListener(this.fname, 'click', mxUtils.bind(this, function(evt)
6856 { 6857 {
6857 var file = this.getCurrentFile(); 6858 var file = this.getCurrentFile();
6858 - 6859 +
6859 if (file != null && file.isRenamable()) 6860 if (file != null && file.isRenamable())
6860 { 6861 {
6861 if (this.editor.graph.isEditing()) 6862 if (this.editor.graph.isEditing())
@@ -6865,23 +6866,23 @@ App.prototype.updateHeader = function() @@ -6865,23 +6866,23 @@ App.prototype.updateHeader = function()
6865 6866
6866 this.actions.get('rename').funct(); 6867 this.actions.get('rename').funct();
6867 } 6868 }
6868 - 6869 +
6869 mxEvent.consume(evt); 6870 mxEvent.consume(evt);
6870 })); 6871 }));
6871 - 6872 +
6872 this.fnameWrapper.appendChild(this.fname); 6873 this.fnameWrapper.appendChild(this.fname);
6873 - 6874 +
6874 if (urlParams['embed'] != '1') 6875 if (urlParams['embed'] != '1')
6875 { 6876 {
6876 this.menubarContainer.appendChild(this.fnameWrapper); 6877 this.menubarContainer.appendChild(this.fnameWrapper);
6877 - 6878 +
6878 this.menubar.container.style.position = 'absolute'; 6879 this.menubar.container.style.position = 'absolute';
6879 this.menubar.container.style.paddingLeft = '59px'; 6880 this.menubar.container.style.paddingLeft = '59px';
6880 this.toolbar.container.style.paddingLeft = '16px'; 6881 this.toolbar.container.style.paddingLeft = '16px';
6881 this.menubar.container.style.boxSizing = 'border-box'; 6882 this.menubar.container.style.boxSizing = 'border-box';
6882 this.menubar.container.style.top = '34px'; 6883 this.menubar.container.style.top = '34px';
6883 } 6884 }
6884 - 6885 +
6885 /** 6886 /**
6886 * Adds format panel toggle. 6887 * Adds format panel toggle.
6887 */ 6888 */
@@ -6899,24 +6900,24 @@ App.prototype.updateHeader = function() @@ -6899,24 +6900,24 @@ App.prototype.updateHeader = function()
6899 this.toggleFormatElement.style.backgroundPosition = '50% 50%'; 6900 this.toggleFormatElement.style.backgroundPosition = '50% 50%';
6900 this.toggleFormatElement.style.backgroundRepeat = 'no-repeat'; 6901 this.toggleFormatElement.style.backgroundRepeat = 'no-repeat';
6901 this.toolbarContainer.appendChild(this.toggleFormatElement); 6902 this.toolbarContainer.appendChild(this.toggleFormatElement);
6902 - 6903 +
6903 if (uiTheme == 'dark') 6904 if (uiTheme == 'dark')
6904 { 6905 {
6905 this.toggleFormatElement.style.filter = 'invert(100%)'; 6906 this.toggleFormatElement.style.filter = 'invert(100%)';
6906 } 6907 }
6907 - 6908 +
6908 // Prevents focus 6909 // Prevents focus
6909 mxEvent.addListener(this.toggleFormatElement, (mxClient.IS_POINTER) ? 'pointerdown' : 'mousedown', 6910 mxEvent.addListener(this.toggleFormatElement, (mxClient.IS_POINTER) ? 'pointerdown' : 'mousedown',
6910 mxUtils.bind(this, function(evt) 6911 mxUtils.bind(this, function(evt)
6911 { 6912 {
6912 evt.preventDefault(); 6913 evt.preventDefault();
6913 })); 6914 }));
6914 - 6915 +
6915 mxEvent.addListener(this.toggleFormatElement, 'click', mxUtils.bind(this, function(evt) 6916 mxEvent.addListener(this.toggleFormatElement, 'click', mxUtils.bind(this, function(evt)
6916 { 6917 {
6917 EditorUi.logEvent({category: 'TOOLBAR-ACTION-', 6918 EditorUi.logEvent({category: 'TOOLBAR-ACTION-',
6918 action: 'formatPanel'}); 6919 action: 'formatPanel'});
6919 - 6920 +
6920 this.actions.get('formatPanel').funct(); 6921 this.actions.get('formatPanel').funct();
6921 mxEvent.consume(evt); 6922 mxEvent.consume(evt);
6922 })); 6923 }));
@@ -6932,7 +6933,7 @@ App.prototype.updateHeader = function() @@ -6932,7 +6933,7 @@ App.prototype.updateHeader = function()
6932 this.toggleFormatElement.style.backgroundImage = 'url(\'' + this.formatHideImage + '\')'; 6933 this.toggleFormatElement.style.backgroundImage = 'url(\'' + this.formatHideImage + '\')';
6933 } 6934 }
6934 }); 6935 });
6935 - 6936 +
6936 this.addListener('formatWidthChanged', toggleFormatPanel); 6937 this.addListener('formatWidthChanged', toggleFormatPanel);
6937 toggleFormatPanel(); 6938 toggleFormatPanel();
6938 6939
@@ -6951,35 +6952,35 @@ App.prototype.updateHeader = function() @@ -6951,35 +6952,35 @@ App.prototype.updateHeader = function()
6951 this.fullscreenElement.style.backgroundRepeat = 'no-repeat'; 6952 this.fullscreenElement.style.backgroundRepeat = 'no-repeat';
6952 this.fullscreenElement.style.backgroundImage = 'url(\'' + this.fullscreenImage + '\')'; 6953 this.fullscreenElement.style.backgroundImage = 'url(\'' + this.fullscreenImage + '\')';
6953 this.toolbarContainer.appendChild(this.fullscreenElement); 6954 this.toolbarContainer.appendChild(this.fullscreenElement);
6954 - 6955 +
6955 // Prevents focus 6956 // Prevents focus
6956 mxEvent.addListener(this.fullscreenElement, (mxClient.IS_POINTER) ? 'pointerdown' : 'mousedown', 6957 mxEvent.addListener(this.fullscreenElement, (mxClient.IS_POINTER) ? 'pointerdown' : 'mousedown',
6957 mxUtils.bind(this, function(evt) 6958 mxUtils.bind(this, function(evt)
6958 { 6959 {
6959 evt.preventDefault(); 6960 evt.preventDefault();
6960 })); 6961 }));
6961 - 6962 +
6962 // Some style changes in Atlas theme 6963 // Some style changes in Atlas theme
6963 if (uiTheme == 'atlas') 6964 if (uiTheme == 'atlas')
6964 { 6965 {
6965 mxUtils.setOpacity(this.toggleFormatElement, 70); 6966 mxUtils.setOpacity(this.toggleFormatElement, 70);
6966 mxUtils.setOpacity(this.fullscreenElement, 70); 6967 mxUtils.setOpacity(this.fullscreenElement, 70);
6967 } 6968 }
6968 - 6969 +
6969 var initialPosition = this.hsplitPosition; 6970 var initialPosition = this.hsplitPosition;
6970 6971
6971 if (uiTheme == 'dark') 6972 if (uiTheme == 'dark')
6972 { 6973 {
6973 this.fullscreenElement.style.filter = 'invert(100%)'; 6974 this.fullscreenElement.style.filter = 'invert(100%)';
6974 } 6975 }
6975 - 6976 +
6976 mxEvent.addListener(this.fullscreenElement, 'click', mxUtils.bind(this, function(evt) 6977 mxEvent.addListener(this.fullscreenElement, 'click', mxUtils.bind(this, function(evt)
6977 { 6978 {
6978 var visible = this.fullscreenMode; 6979 var visible = this.fullscreenMode;
6979 6980
6980 EditorUi.logEvent({category: 'TOOLBAR-ACTION-', 6981 EditorUi.logEvent({category: 'TOOLBAR-ACTION-',
6981 action: 'fullscreen' , currentstate: visible}); 6982 action: 'fullscreen' , currentstate: visible});
6982 - 6983 +
6983 if (uiTheme != 'atlas' && urlParams['embed'] != '1') 6984 if (uiTheme != 'atlas' && urlParams['embed'] != '1')
6984 { 6985 {
6985 this.toggleCompactMode(visible); 6986 this.toggleCompactMode(visible);
@@ -6989,7 +6990,7 @@ App.prototype.updateHeader = function() @@ -6989,7 +6990,7 @@ App.prototype.updateHeader = function()
6989 { 6990 {
6990 initialPosition = this.hsplitPosition; 6991 initialPosition = this.hsplitPosition;
6991 } 6992 }
6992 - 6993 +
6993 this.hsplitPosition = (visible) ? initialPosition : 0; 6994 this.hsplitPosition = (visible) ? initialPosition : 0;
6994 this.toggleFormatPanel(visible); 6995 this.toggleFormatPanel(visible);
6995 this.fullscreenMode = !visible; 6996 this.fullscreenMode = !visible;
@@ -7015,22 +7016,22 @@ App.prototype.updateHeader = function() @@ -7015,22 +7016,22 @@ App.prototype.updateHeader = function()
7015 this.toggleElement.style.fontSize = '14px'; 7016 this.toggleElement.style.fontSize = '14px';
7016 this.toggleElement.style.textDecoration = 'none'; 7017 this.toggleElement.style.textDecoration = 'none';
7017 this.toggleElement.style.backgroundImage = 'url(\'' + this.chevronUpImage + '\')'; 7018 this.toggleElement.style.backgroundImage = 'url(\'' + this.chevronUpImage + '\')';
7018 - 7019 +
7019 this.toggleElement.style.backgroundPosition = '50% 50%'; 7020 this.toggleElement.style.backgroundPosition = '50% 50%';
7020 this.toggleElement.style.backgroundRepeat = 'no-repeat'; 7021 this.toggleElement.style.backgroundRepeat = 'no-repeat';
7021 - 7022 +
7022 if (uiTheme == 'dark') 7023 if (uiTheme == 'dark')
7023 { 7024 {
7024 this.toggleElement.style.filter = 'invert(100%)'; 7025 this.toggleElement.style.filter = 'invert(100%)';
7025 } 7026 }
7026 - 7027 +
7027 // Prevents focus 7028 // Prevents focus
7028 mxEvent.addListener(this.toggleElement, (mxClient.IS_POINTER) ? 'pointerdown' : 'mousedown', 7029 mxEvent.addListener(this.toggleElement, (mxClient.IS_POINTER) ? 'pointerdown' : 'mousedown',
7029 mxUtils.bind(this, function(evt) 7030 mxUtils.bind(this, function(evt)
7030 { 7031 {
7031 evt.preventDefault(); 7032 evt.preventDefault();
7032 })); 7033 }));
7033 - 7034 +
7034 // Toggles compact mode 7035 // Toggles compact mode
7035 mxEvent.addListener(this.toggleElement, 'click', mxUtils.bind(this, function(evt) 7036 mxEvent.addListener(this.toggleElement, 'click', mxUtils.bind(this, function(evt)
7036 { 7037 {
@@ -7039,12 +7040,12 @@ App.prototype.updateHeader = function() @@ -7039,12 +7040,12 @@ App.prototype.updateHeader = function()
7039 this.toggleCompactMode(); 7040 this.toggleCompactMode();
7040 mxEvent.consume(evt); 7041 mxEvent.consume(evt);
7041 })); 7042 }));
7042 - 7043 +
7043 if (uiTheme != 'atlas') 7044 if (uiTheme != 'atlas')
7044 { 7045 {
7045 this.toolbarContainer.appendChild(this.toggleElement); 7046 this.toolbarContainer.appendChild(this.toggleElement);
7046 } 7047 }
7047 - 7048 +
7048 // Enable compact mode for small screens except for Firefox where the height is wrong 7049 // Enable compact mode for small screens except for Firefox where the height is wrong
7049 if (!mxClient.IS_FF && screen.height <= 740 && typeof this.toggleElement.click !== 'undefined') 7050 if (!mxClient.IS_FF && screen.height <= 740 && typeof this.toggleElement.click !== 'undefined')
7050 { 7051 {
@@ -7065,7 +7066,7 @@ App.prototype.updateHeader = function() @@ -7065,7 +7066,7 @@ App.prototype.updateHeader = function()
7065 App.prototype.toggleCompactMode = function(visible) 7066 App.prototype.toggleCompactMode = function(visible)
7066 { 7067 {
7067 visible = (visible != null) ? visible : this.compactMode; 7068 visible = (visible != null) ? visible : this.compactMode;
7068 - 7069 +
7069 if (visible) 7070 if (visible)
7070 { 7071 {
7071 this.menubar.container.style.position = 'absolute'; 7072 this.menubar.container.style.position = 'absolute';
@@ -7098,7 +7099,7 @@ App.prototype.toggleCompactMode = function(visible) @@ -7098,7 +7099,7 @@ App.prototype.toggleCompactMode = function(visible)
7098 this.refresh(); 7099 this.refresh();
7099 this.toggleElement.style.backgroundImage = 'url(\'' + this.chevronDownImage + '\')'; 7100 this.toggleElement.style.backgroundImage = 'url(\'' + this.chevronDownImage + '\')';
7100 } 7101 }
7101 - 7102 +
7102 this.compactMode = !visible; 7103 this.compactMode = !visible;
7103 }; 7104 };
7104 7105
@@ -7138,7 +7139,7 @@ App.prototype.updateUserElement = function() @@ -7138,7 +7139,7 @@ App.prototype.updateUserElement = function()
7138 this.userElement.style.backgroundImage = 'url(' + IMAGE_PATH + '/expanded.gif)'; 7139 this.userElement.style.backgroundImage = 'url(' + IMAGE_PATH + '/expanded.gif)';
7139 this.userElement.style.backgroundPosition = '100% 60%'; 7140 this.userElement.style.backgroundPosition = '100% 60%';
7140 this.userElement.style.backgroundRepeat = 'no-repeat'; 7141 this.userElement.style.backgroundRepeat = 'no-repeat';
7141 - 7142 +
7142 this.menubarContainer.appendChild(this.userElement); 7143 this.menubarContainer.appendChild(this.userElement);
7143 7144
7144 // Prevents focus 7145 // Prevents focus
@@ -7162,10 +7163,10 @@ App.prototype.updateUserElement = function() @@ -7162,10 +7163,10 @@ App.prototype.updateUserElement = function()
7162 div.style.padding = '0px'; 7163 div.style.padding = '0px';
7163 div.style.cursor = 'default'; 7164 div.style.cursor = 'default';
7164 div.style.minWidth = '300px'; 7165 div.style.minWidth = '300px';
7165 - 7166 +
7166 this.userPanel = div; 7167 this.userPanel = div;
7167 } 7168 }
7168 - 7169 +
7169 if (this.userPanel.parentNode != null) 7170 if (this.userPanel.parentNode != null)
7170 { 7171 {
7171 this.userPanel.parentNode.removeChild(this.userPanel); 7172 this.userPanel.parentNode.removeChild(this.userPanel);
@@ -7174,7 +7175,7 @@ App.prototype.updateUserElement = function() @@ -7174,7 +7175,7 @@ App.prototype.updateUserElement = function()
7174 { 7175 {
7175 var connected = false; 7176 var connected = false;
7176 this.userPanel.innerHTML = ''; 7177 this.userPanel.innerHTML = '';
7177 - 7178 +
7178 var img = document.createElement('img'); 7179 var img = document.createElement('img');
7179 7180
7180 img.setAttribute('src', Dialog.prototype.closeImage); 7181 img.setAttribute('src', Dialog.prototype.closeImage);
@@ -7182,7 +7183,7 @@ App.prototype.updateUserElement = function() @@ -7182,7 +7183,7 @@ App.prototype.updateUserElement = function()
7182 img.className = 'geDialogClose'; 7183 img.className = 'geDialogClose';
7183 img.style.top = '8px'; 7184 img.style.top = '8px';
7184 img.style.right = '8px'; 7185 img.style.right = '8px';
7185 - 7186 +
7186 mxEvent.addListener(img, 'click', mxUtils.bind(this, function() 7187 mxEvent.addListener(img, 'click', mxUtils.bind(this, function()
7187 { 7188 {
7188 if (this.userPanel.parentNode != null) 7189 if (this.userPanel.parentNode != null)
@@ -7190,13 +7191,13 @@ App.prototype.updateUserElement = function() @@ -7190,13 +7191,13 @@ App.prototype.updateUserElement = function()
7190 this.userPanel.parentNode.removeChild(this.userPanel); 7191 this.userPanel.parentNode.removeChild(this.userPanel);
7191 } 7192 }
7192 })); 7193 }));
7193 - 7194 +
7194 this.userPanel.appendChild(img); 7195 this.userPanel.appendChild(img);
7195 - 7196 +
7196 if (this.drive != null) 7197 if (this.drive != null)
7197 { 7198 {
7198 var driveUsers = this.drive.getUsersList(); 7199 var driveUsers = this.drive.getUsersList();
7199 - 7200 +
7200 if (driveUsers.length > 0) 7201 if (driveUsers.length > 0)
7201 { 7202 {
7202 // LATER: Cannot change user while file is open since close will not work with new 7203 // LATER: Cannot change user while file is open since close will not work with new
@@ -7208,7 +7209,7 @@ App.prototype.updateUserElement = function() @@ -7208,7 +7209,7 @@ App.prototype.updateUserElement = function()
7208 if (file != null && file.constructor == DriveFile) 7209 if (file != null && file.constructor == DriveFile)
7209 { 7210 {
7210 this.spinner.spin(document.body, spinnerMsg); 7211 this.spinner.spin(document.body, spinnerMsg);
7211 - 7212 +
7212 // file.close(); 7213 // file.close();
7213 this.fileLoaded(null); 7214 this.fileLoaded(null);
7214 7215
@@ -7224,7 +7225,7 @@ App.prototype.updateUserElement = function() @@ -7224,7 +7225,7 @@ App.prototype.updateUserElement = function()
7224 callback(); 7225 callback();
7225 } 7226 }
7226 }); 7227 });
7227 - 7228 +
7228 var createUserRow = mxUtils.bind(this, function (user) 7229 var createUserRow = mxUtils.bind(this, function (user)
7229 { 7230 {
7230 var tr = document.createElement('tr'); 7231 var tr = document.createElement('tr');
@@ -7244,7 +7245,7 @@ App.prototype.updateUserElement = function() @@ -7244,7 +7245,7 @@ App.prototype.updateUserElement = function()
7244 img.style.margin = '4px 8px 0 8px'; 7245 img.style.margin = '4px 8px 0 8px';
7245 td.appendChild(img); 7246 td.appendChild(img);
7246 tr.appendChild(td); 7247 tr.appendChild(td);
7247 - 7248 +
7248 var td = document.createElement('td'); 7249 var td = document.createElement('td');
7249 td.setAttribute('valign', 'middle'); 7250 td.setAttribute('valign', 'middle');
7250 td.style.whiteSpace = 'nowrap'; 7251 td.style.whiteSpace = 'nowrap';
@@ -7255,17 +7256,17 @@ App.prototype.updateUserElement = function() @@ -7255,17 +7256,17 @@ App.prototype.updateUserElement = function()
7255 mxUtils.write(td, user.displayName + 7256 mxUtils.write(td, user.displayName +
7256 ((user.isCurrent && driveUsers.length > 1) ? 7257 ((user.isCurrent && driveUsers.length > 1) ?
7257 ' (' + mxResources.get('default') + ')' : '')); 7258 ' (' + mxResources.get('default') + ')' : ''));
7258 - 7259 +
7259 if (user.email != null) 7260 if (user.email != null)
7260 { 7261 {
7261 mxUtils.br(td); 7262 mxUtils.br(td);
7262 - 7263 +
7263 var small = document.createElement('small'); 7264 var small = document.createElement('small');
7264 small.style.color = 'gray'; 7265 small.style.color = 'gray';
7265 mxUtils.write(small, user.email); 7266 mxUtils.write(small, user.email);
7266 td.appendChild(small); 7267 td.appendChild(small);
7267 } 7268 }
7268 - 7269 +
7269 var div = document.createElement('div'); 7270 var div = document.createElement('div');
7270 div.style.marginTop = '4px'; 7271 div.style.marginTop = '4px';
7271 7272
@@ -7286,7 +7287,7 @@ App.prototype.updateUserElement = function() @@ -7286,7 +7287,7 @@ App.prototype.updateUserElement = function()
7286 { 7287 {
7287 this.stateArg = null; 7288 this.stateArg = null;
7288 this.drive.setUser(user); 7289 this.drive.setUser(user);
7289 - 7290 +
7290 this.drive.authorize(true, mxUtils.bind(this, function() 7291 this.drive.authorize(true, mxUtils.bind(this, function()
7291 { 7292 {
7292 this.setMode(App.MODE_GOOGLE); 7293 this.setMode(App.MODE_GOOGLE);
@@ -7297,16 +7298,16 @@ App.prototype.updateUserElement = function() @@ -7297,16 +7298,16 @@ App.prototype.updateUserElement = function()
7297 this.handleError(resp); 7298 this.handleError(resp);
7298 }), true); //Remember is true since add account imply keeping that account 7299 }), true); //Remember is true since add account imply keeping that account
7299 }), mxResources.get('closingFile') + '...'); 7300 }), mxResources.get('closingFile') + '...');
7300 - 7301 +
7301 mxEvent.consume(evt); 7302 mxEvent.consume(evt);
7302 })); 7303 }));
7303 } 7304 }
7304 - 7305 +
7305 return tr; 7306 return tr;
7306 }); 7307 });
7307 - 7308 +
7308 connected = true; 7309 connected = true;
7309 - 7310 +
7310 var driveUserTable = document.createElement('table'); 7311 var driveUserTable = document.createElement('table');
7311 driveUserTable.style.borderSpacing = '0'; 7312 driveUserTable.style.borderSpacing = '0';
7312 driveUserTable.style.fontSize = '10pt'; 7313 driveUserTable.style.fontSize = '10pt';
@@ -7317,9 +7318,9 @@ App.prototype.updateUserElement = function() @@ -7317,9 +7318,9 @@ App.prototype.updateUserElement = function()
7317 { 7318 {
7318 driveUserTable.appendChild(createUserRow(driveUsers[i])); 7319 driveUserTable.appendChild(createUserRow(driveUsers[i]));
7319 } 7320 }
7320 - 7321 +
7321 this.userPanel.appendChild(driveUserTable); 7322 this.userPanel.appendChild(driveUserTable);
7322 - 7323 +
7323 var div = document.createElement('div'); 7324 var div = document.createElement('div');
7324 div.style.textAlign = 'left'; 7325 div.style.textAlign = 'left';
7325 div.style.padding = '10px'; 7326 div.style.padding = '10px';
@@ -7343,18 +7344,18 @@ App.prototype.updateUserElement = function() @@ -7343,18 +7344,18 @@ App.prototype.updateUserElement = function()
7343 btn.className = 'geBtn'; 7344 btn.className = 'geBtn';
7344 btn.style.float = 'right'; 7345 btn.style.float = 'right';
7345 div.appendChild(btn); 7346 div.appendChild(btn);
7346 - 7347 +
7347 var btn = mxUtils.button(mxResources.get('addAccount'), mxUtils.bind(this, function() 7348 var btn = mxUtils.button(mxResources.get('addAccount'), mxUtils.bind(this, function()
7348 { 7349 {
7349 var authWin = this.drive.createAuthWin(); 7350 var authWin = this.drive.createAuthWin();
7350 //FIXME This doean't work to set focus back to main window until closing the file is done 7351 //FIXME This doean't work to set focus back to main window until closing the file is done
7351 authWin.blur(); 7352 authWin.blur();
7352 window.focus(); 7353 window.focus();
7353 - 7354 +
7354 closeFile(mxUtils.bind(this, function() 7355 closeFile(mxUtils.bind(this, function()
7355 { 7356 {
7356 this.stateArg = null; 7357 this.stateArg = null;
7357 - 7358 +
7358 this.drive.authorize(false, mxUtils.bind(this, function() 7359 this.drive.authorize(false, mxUtils.bind(this, function()
7359 { 7360 {
7360 this.setMode(App.MODE_GOOGLE); 7361 this.setMode(App.MODE_GOOGLE);
@@ -7372,7 +7373,7 @@ App.prototype.updateUserElement = function() @@ -7372,7 +7373,7 @@ App.prototype.updateUserElement = function()
7372 this.userPanel.appendChild(div); 7373 this.userPanel.appendChild(div);
7373 } 7374 }
7374 } 7375 }
7375 - 7376 +
7376 var addUser = mxUtils.bind(this, function(user, logo, logout, label) 7377 var addUser = mxUtils.bind(this, function(user, logo, logout, label)
7377 { 7378 {
7378 if (user != null) 7379 if (user != null)
@@ -7381,7 +7382,7 @@ App.prototype.updateUserElement = function() @@ -7381,7 +7382,7 @@ App.prototype.updateUserElement = function()
7381 { 7382 {
7382 this.userPanel.appendChild(document.createElement('hr')); 7383 this.userPanel.appendChild(document.createElement('hr'));
7383 } 7384 }
7384 - 7385 +
7385 connected = true; 7386 connected = true;
7386 var userTable = document.createElement('table'); 7387 var userTable = document.createElement('table');
7387 userTable.style.borderSpacing = '0'; 7388 userTable.style.borderSpacing = '0';
@@ -7448,18 +7449,18 @@ App.prototype.updateUserElement = function() @@ -7448,18 +7449,18 @@ App.prototype.updateUserElement = function()
7448 div.style.textAlign = 'center'; 7449 div.style.textAlign = 'center';
7449 div.style.padding = '10px'; 7450 div.style.padding = '10px';
7450 div.style.whiteSpace = 'nowrap'; 7451 div.style.whiteSpace = 'nowrap';
7451 - 7452 +
7452 if (logout != null) 7453 if (logout != null)
7453 { 7454 {
7454 var btn = mxUtils.button(mxResources.get('signOut'), logout); 7455 var btn = mxUtils.button(mxResources.get('signOut'), logout);
7455 btn.className = 'geBtn'; 7456 btn.className = 'geBtn';
7456 div.appendChild(btn); 7457 div.appendChild(btn);
7457 } 7458 }
7458 - 7459 +
7459 this.userPanel.appendChild(div); 7460 this.userPanel.appendChild(div);
7460 } 7461 }
7461 }); 7462 });
7462 - 7463 +
7463 if (this.dropbox != null) 7464 if (this.dropbox != null)
7464 { 7465 {
7465 addUser(this.dropbox.getUser(), IMAGE_PATH + '/dropbox-logo.svg', mxUtils.bind(this, function() 7466 addUser(this.dropbox.getUser(), IMAGE_PATH + '/dropbox-logo.svg', mxUtils.bind(this, function()
@@ -7473,7 +7474,7 @@ App.prototype.updateUserElement = function() @@ -7473,7 +7474,7 @@ App.prototype.updateUserElement = function()
7473 this.dropbox.logout(); 7474 this.dropbox.logout();
7474 window.location.hash = ''; 7475 window.location.hash = '';
7475 }); 7476 });
7476 - 7477 +
7477 if (!file.isModified()) 7478 if (!file.isModified())
7478 { 7479 {
7479 doLogout(); 7480 doLogout();
@@ -7504,7 +7505,7 @@ App.prototype.updateUserElement = function() @@ -7504,7 +7505,7 @@ App.prototype.updateUserElement = function()
7504 this.oneDrive.logout(); 7505 this.oneDrive.logout();
7505 window.location.hash = ''; 7506 window.location.hash = '';
7506 }); 7507 });
7507 - 7508 +
7508 if (!file.isModified()) 7509 if (!file.isModified())
7509 { 7510 {
7510 doLogout(); 7511 doLogout();
@@ -7535,7 +7536,7 @@ App.prototype.updateUserElement = function() @@ -7535,7 +7536,7 @@ App.prototype.updateUserElement = function()
7535 this.gitHub.logout(); 7536 this.gitHub.logout();
7536 window.location.hash = ''; 7537 window.location.hash = '';
7537 }); 7538 });
7538 - 7539 +
7539 if (!file.isModified()) 7540 if (!file.isModified())
7540 { 7541 {
7541 doLogout(); 7542 doLogout();
@@ -7552,7 +7553,7 @@ App.prototype.updateUserElement = function() @@ -7552,7 +7553,7 @@ App.prototype.updateUserElement = function()
7552 } 7553 }
7553 }), mxResources.get('github')); 7554 }), mxResources.get('github'));
7554 } 7555 }
7555 - 7556 +
7556 if (this.gitLab != null) 7557 if (this.gitLab != null)
7557 { 7558 {
7558 addUser(this.gitLab.getUser(), IMAGE_PATH + '/gitlab-logo.svg', mxUtils.bind(this, function() 7559 addUser(this.gitLab.getUser(), IMAGE_PATH + '/gitlab-logo.svg', mxUtils.bind(this, function()
@@ -7598,7 +7599,7 @@ App.prototype.updateUserElement = function() @@ -7598,7 +7599,7 @@ App.prototype.updateUserElement = function()
7598 this.trello.logout(); 7599 this.trello.logout();
7599 window.location.hash = ''; 7600 window.location.hash = '';
7600 }); 7601 });
7601 - 7602 +
7602 if (!file.isModified()) 7603 if (!file.isModified())
7603 { 7604 {
7604 doLogout(); 7605 doLogout();
@@ -7615,24 +7616,24 @@ App.prototype.updateUserElement = function() @@ -7615,24 +7616,24 @@ App.prototype.updateUserElement = function()
7615 } 7616 }
7616 }), mxResources.get('trello')); 7617 }), mxResources.get('trello'));
7617 } 7618 }
7618 - 7619 +
7619 if (!connected) 7620 if (!connected)
7620 { 7621 {
7621 var div = document.createElement('div'); 7622 var div = document.createElement('div');
7622 div.style.textAlign = 'center'; 7623 div.style.textAlign = 'center';
7623 div.style.padding = '10px'; 7624 div.style.padding = '10px';
7624 div.innerHTML = mxResources.get('notConnected'); 7625 div.innerHTML = mxResources.get('notConnected');
7625 - 7626 +
7626 this.userPanel.appendChild(div); 7627 this.userPanel.appendChild(div);
7627 } 7628 }
7628 - 7629 +
7629 var div = document.createElement('div'); 7630 var div = document.createElement('div');
7630 div.style.textAlign = 'center'; 7631 div.style.textAlign = 'center';
7631 div.style.padding = '10px'; 7632 div.style.padding = '10px';
7632 div.style.background = Editor.isDarkMode() ? '' : 'whiteSmoke'; 7633 div.style.background = Editor.isDarkMode() ? '' : 'whiteSmoke';
7633 div.style.borderTop = '1px solid #e0e0e0'; 7634 div.style.borderTop = '1px solid #e0e0e0';
7634 div.style.whiteSpace = 'nowrap'; 7635 div.style.whiteSpace = 'nowrap';
7635 - 7636 +
7636 if (urlParams['sketch'] == '1') 7637 if (urlParams['sketch'] == '1')
7637 { 7638 {
7638 var btn = mxUtils.button(mxResources.get('share'), mxUtils.bind(this, function() 7639 var btn = mxUtils.button(mxResources.get('share'), mxUtils.bind(this, function()
@@ -7642,7 +7643,7 @@ App.prototype.updateUserElement = function() @@ -7642,7 +7643,7 @@ App.prototype.updateUserElement = function()
7642 btn.className = 'geBtn'; 7643 btn.className = 'geBtn';
7643 div.appendChild(btn); 7644 div.appendChild(btn);
7644 this.userPanel.appendChild(div); 7645 this.userPanel.appendChild(div);
7645 - 7646 +
7646 if (this.commentsSupported()) 7647 if (this.commentsSupported())
7647 { 7648 {
7648 btn = mxUtils.button(mxResources.get('comments'), mxUtils.bind(this, function() 7649 btn = mxUtils.button(mxResources.get('comments'), mxUtils.bind(this, function()
@@ -7670,10 +7671,10 @@ App.prototype.updateUserElement = function() @@ -7670,10 +7671,10 @@ App.prototype.updateUserElement = function()
7670 7671
7671 document.body.appendChild(this.userPanel); 7672 document.body.appendChild(this.userPanel);
7672 } 7673 }
7673 - 7674 +
7674 mxEvent.consume(evt); 7675 mxEvent.consume(evt);
7675 })); 7676 }));
7676 - 7677 +
7677 mxEvent.addListener(document.body, 'click', mxUtils.bind(this, function(evt) 7678 mxEvent.addListener(document.body, 'click', mxUtils.bind(this, function(evt)
7678 { 7679 {
7679 if (!mxEvent.isConsumed(evt) && this.userPanel != null && this.userPanel.parentNode != null) 7680 if (!mxEvent.isConsumed(evt) && this.userPanel != null && this.userPanel.parentNode != null)
@@ -7682,9 +7683,9 @@ App.prototype.updateUserElement = function() @@ -7682,9 +7683,9 @@ App.prototype.updateUserElement = function()
7682 } 7683 }
7683 })); 7684 }));
7684 } 7685 }
7685 - 7686 +
7686 var user = null; 7687 var user = null;
7687 - 7688 +
7688 if (this.drive != null && this.drive.getUser() != null) 7689 if (this.drive != null && this.drive.getUser() != null)
7689 { 7690 {
7690 user = this.drive.getUser(); 7691 user = this.drive.getUser();
@@ -7706,11 +7707,11 @@ App.prototype.updateUserElement = function() @@ -7706,11 +7707,11 @@ App.prototype.updateUserElement = function()
7706 user = this.gitLab.getUser(); 7707 user = this.gitLab.getUser();
7707 } 7708 }
7708 //TODO Trello no user issue 7709 //TODO Trello no user issue
7709 - 7710 +
7710 if (user != null) 7711 if (user != null)
7711 { 7712 {
7712 this.userElement.innerHTML = ''; 7713 this.userElement.innerHTML = '';
7713 - 7714 +
7714 if (screen.width > 560) 7715 if (screen.width > 560)
7715 { 7716 {
7716 mxUtils.write(this.userElement, user.displayName); 7717 mxUtils.write(this.userElement, user.displayName);
@@ -7728,7 +7729,7 @@ App.prototype.updateUserElement = function() @@ -7728,7 +7729,7 @@ App.prototype.updateUserElement = function()
7728 App.prototype.getCurrentUser = function() 7729 App.prototype.getCurrentUser = function()
7729 { 7730 {
7730 var user = null; 7731 var user = null;
7731 - 7732 +
7732 if (this.drive != null && this.drive.getUser() != null) 7733 if (this.drive != null && this.drive.getUser() != null)
7733 { 7734 {
7734 user = this.drive.getUser(); 7735 user = this.drive.getUser();
@@ -7746,17 +7747,17 @@ App.prototype.getCurrentUser = function() @@ -7746,17 +7747,17 @@ App.prototype.getCurrentUser = function()
7746 user = this.gitHub.getUser(); 7747 user = this.gitHub.getUser();
7747 } 7748 }
7748 //TODO Trello no user issue 7749 //TODO Trello no user issue
7749 - 7750 +
7750 return user; 7751 return user;
7751 } 7752 }
7752 /** 7753 /**
7753 * Override depends on mxSettings which is not defined in the minified viewer. 7754 * Override depends on mxSettings which is not defined in the minified viewer.
7754 */ 7755 */
7755 -var editorResetGraph = Editor.prototype.resetGraph; 7756 +var editorResetGraph = Editor.prototype.resetGraph;
7756 Editor.prototype.resetGraph = function() 7757 Editor.prototype.resetGraph = function()
7757 { 7758 {
7758 editorResetGraph.apply(this, arguments); 7759 editorResetGraph.apply(this, arguments);
7759 - 7760 +
7760 // Overrides default with persisted value 7761 // Overrides default with persisted value
7761 if (this.graph.defaultPageFormat == null) 7762 if (this.graph.defaultPageFormat == null)
7762 { 7763 {