1/** 2 * Copyright (c) 2006-2017, JGraph Ltd 3 * Copyright (c) 2006-2017, Gaudenz Alder 4 */ 5GitHubFile = function(ui, data, meta) 6{ 7 DrawioFile.call(this, ui, data); 8 9 this.meta = meta; 10 this.peer = this.ui.gitHub; 11}; 12 13//Extends mxEventSource 14mxUtils.extend(GitHubFile, DrawioFile); 15 16/** 17 * Translates this point by the given vector. 18 * 19 * @param {number} dx X-coordinate of the translation. 20 * @param {number} dy Y-coordinate of the translation. 21 */ 22GitHubFile.prototype.share = function() 23{ 24 this.ui.editor.graph.openLink('https://github.com/' + 25 encodeURIComponent(this.meta.org) + '/' + 26 encodeURIComponent(this.meta.repo) +'/settings/access'); 27}; 28 29/** 30 * Translates this point by the given vector. 31 * 32 * @param {number} dx X-coordinate of the translation. 33 * @param {number} dy Y-coordinate of the translation. 34 */ 35GitHubFile.prototype.getId = function() 36{ 37 return encodeURIComponent(this.meta.org) + '/' + 38 ((this.meta.repo != null) ? encodeURIComponent(this.meta.repo) + '/' + 39 ((this.meta.ref != null) ? this.meta.ref + 40 ((this.meta.path != null) ? '/' + this.meta.path : '') : '') : ''); 41}; 42 43/** 44 * Translates this point by the given vector. 45 * 46 * @param {number} dx X-coordinate of the translation. 47 * @param {number} dy Y-coordinate of the translation. 48 */ 49GitHubFile.prototype.getHash = function() 50{ 51 return encodeURIComponent('H' + this.getId()); 52}; 53 54/** 55 * Returns true if copy, export and print are not allowed for this file. 56 */ 57GitHubFile.prototype.getPublicUrl = function(fn) 58{ 59 // LATER: Check if download_url is always null for private repos 60 if (this.meta.download_url != null) 61 { 62 mxUtils.get(this.meta.download_url, mxUtils.bind(this, function(req) 63 { 64 fn((req.getStatus() >= 200 && req.getStatus() <= 299) ? this.meta.download_url : null); 65 }), mxUtils.bind(this, function() 66 { 67 fn(null); 68 })); 69 } 70 else 71 { 72 fn(null); 73 } 74}; 75 76/** 77 * Adds the listener for automatically saving the diagram for local changes. 78 */ 79GitHubFile.prototype.isConflict = function(err) 80{ 81 return err != null && err.status == 409; 82}; 83 84/** 85 * Translates this point by the given vector. 86 * 87 * @param {number} dx X-coordinate of the translation. 88 * @param {number} dy Y-coordinate of the translation. 89 */ 90GitHubFile.prototype.getMode = function() 91{ 92 return App.MODE_GITHUB; 93}; 94 95/** 96 * Overridden to enable the autosave option in the document properties dialog. 97 */ 98GitHubFile.prototype.isAutosave = function() 99{ 100 return false; 101}; 102 103/** 104 * Translates this point by the given vector. 105 * 106 * @param {number} dx X-coordinate of the translation. 107 * @param {number} dy Y-coordinate of the translation. 108 */ 109GitHubFile.prototype.getTitle = function() 110{ 111 return this.meta.name; 112}; 113 114/** 115 * Translates this point by the given vector. 116 * 117 * @param {number} dx X-coordinate of the translation. 118 * @param {number} dy Y-coordinate of the translation. 119 */ 120GitHubFile.prototype.isRenamable = function() 121{ 122 return false; 123}; 124 125/** 126 * Adds the listener for automatically saving the diagram for local changes. 127 */ 128GitHubFile.prototype.getLatestVersion = function(success, error) 129{ 130 this.peer.getFile(this.getId(), success, error); 131}; 132 133/** 134 * Translates this point by the given vector. 135 * 136 * @param {number} dx X-coordinate of the translation. 137 * @param {number} dy Y-coordinate of the translation. 138 */ 139GitHubFile.prototype.isCompressedStorage = function() 140{ 141 return false; 142}; 143 144/** 145 * Hook for subclassers to update the descriptor from given file 146 */ 147GitHubFile.prototype.getDescriptor = function() 148{ 149 return this.meta; 150}; 151 152/** 153 * Hook for subclassers to update the descriptor from given file 154 */ 155GitHubFile.prototype.setDescriptor = function(desc) 156{ 157 this.meta = desc; 158}; 159 160/** 161 * Adds all listeners. 162 */ 163GitHubFile.prototype.getDescriptorEtag = function(desc) 164{ 165 return desc.sha; 166}; 167 168/** 169 * Adds the listener for automatically saving the diagram for local changes. 170 */ 171GitHubFile.prototype.setDescriptorEtag = function(desc, etag) 172{ 173 desc.sha = etag; 174}; 175 176/** 177 * Translates this point by the given vector. 178 * 179 * @param {number} dx X-coordinate of the translation. 180 * @param {number} dy Y-coordinate of the translation. 181 */ 182GitHubFile.prototype.save = function(revision, success, error, unloading, overwrite, message) 183{ 184 this.doSave(this.getTitle(), success, error, unloading, overwrite, message); 185}; 186 187/** 188 * Translates this point by the given vector. 189 * 190 * @param {number} dx X-coordinate of the translation. 191 * @param {number} dy Y-coordinate of the translation. 192 */ 193GitHubFile.prototype.saveAs = function(title, success, error) 194{ 195 this.doSave(title, success, error); 196}; 197 198/** 199 * Translates this point by the given vector. 200 * 201 * @param {number} dx X-coordinate of the translation. 202 * @param {number} dy Y-coordinate of the translation. 203 */ 204GitHubFile.prototype.doSave = function(title, success, error, unloading, overwrite, message) 205{ 206 // Forces update of data for new extensions 207 var prev = this.meta.name; 208 this.meta.name = title; 209 210 DrawioFile.prototype.save.apply(this, [null, mxUtils.bind(this, function() 211 { 212 this.meta.name = prev; 213 this.saveFile(title, false, success, error, unloading, overwrite, message); 214 }), error, unloading, overwrite]); 215}; 216 217/** 218 * Translates this point by the given vector. 219 * 220 * @param {number} dx X-coordinate of the translation. 221 * @param {number} dy Y-coordinate of the translation. 222 */ 223GitHubFile.prototype.saveFile = function(title, revision, success, error, unloading, overwrite, message) 224{ 225 if (!this.isEditable()) 226 { 227 if (success != null) 228 { 229 success(); 230 } 231 } 232 else if (!this.savingFile) 233 { 234 var doSave = mxUtils.bind(this, function(message) 235 { 236 if (this.getTitle() == title) 237 { 238 try 239 { 240 // Sets shadow modified state during save 241 this.savingFileTime = new Date(); 242 this.setShadowModified(false); 243 this.savingFile = true; 244 245 var savedEtag = this.getCurrentEtag(); 246 var savedData = this.data; 247 248 this.peer.saveFile(this, mxUtils.bind(this, function(etag) 249 { 250 // Checks for changes during save 251 this.setModified(this.getShadowModified()); 252 this.savingFile = false; 253 this.setDescriptorEtag(this.meta, etag); 254 255 this.fileSaved(savedData, savedEtag, mxUtils.bind(this, function() 256 { 257 this.contentChanged(); 258 259 if (success != null) 260 { 261 success(); 262 } 263 }), error); 264 }), 265 mxUtils.bind(this, function(err) 266 { 267 this.savingFile = false; 268 269 if (this.isConflict(err)) 270 { 271 this.inConflictState = true; 272 273 if (error != null) 274 { 275 // Passes current commit message to avoid 276 // multiple dialogs after synchronize 277 error({commitMessage: message}); 278 } 279 } 280 else if (error != null) 281 { 282 error(err); 283 } 284 }), overwrite, message); 285 } 286 catch (e) 287 { 288 this.savingFile = false; 289 290 if (error != null) 291 { 292 error(e); 293 } 294 else 295 { 296 throw e; 297 } 298 } 299 } 300 else 301 { 302 // Sets shadow modified state during save 303 this.savingFileTime = new Date(); 304 this.setShadowModified(false); 305 this.savingFile = true; 306 307 this.ui.pickFolder(this.getMode(), mxUtils.bind(this, function(folderId) 308 { 309 this.peer.insertFile(title, this.getData(), mxUtils.bind(this, function(file) 310 { 311 // Checks for changes during save 312 this.setModified(this.getShadowModified()); 313 this.savingFile = false; 314 315 if (success != null) 316 { 317 success(); 318 } 319 320 this.ui.fileLoaded(file); 321 }), mxUtils.bind(this, function() 322 { 323 this.savingFile = false; 324 325 if (error != null) 326 { 327 error(); 328 } 329 }), false, folderId, message); 330 })); 331 } 332 }); 333 334 if (message != null) 335 { 336 doSave(message); 337 } 338 else 339 { 340 this.peer.showCommitDialog(this.meta.name, 341 this.getDescriptorEtag(this.meta) == null || 342 this.meta.isNew, mxUtils.bind(this, function(message) 343 { 344 doSave(message); 345 }), error); 346 } 347 } 348 else if (error != null) 349 { 350 error({code: App.ERROR_BUSY}); 351 } 352}; 353