Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright (C) 2011 Google Inc. All rights reserved. | 2 * Copyright (C) 2011 Google Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
| 6 * met: | 6 * met: |
| 7 * | 7 * |
| 8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
| 9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
| 10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 49 this._name = parsedURL.lastPathComponent; | 49 this._name = parsedURL.lastPathComponent; |
| 50 if (parsedURL.queryParams) | 50 if (parsedURL.queryParams) |
| 51 this._name += '?' + parsedURL.queryParams; | 51 this._name += '?' + parsedURL.queryParams; |
| 52 } else { | 52 } else { |
| 53 this._origin = ''; | 53 this._origin = ''; |
| 54 this._parentURL = ''; | 54 this._parentURL = ''; |
| 55 this._name = url; | 55 this._name = url; |
| 56 } | 56 } |
| 57 | 57 |
| 58 this._contentType = contentType; | 58 this._contentType = contentType; |
| 59 /** @type {?function(?string)} */ | |
| 60 this._requestContentCallback = null; | |
| 61 /** @type {?Promise<?string>} */ | 59 /** @type {?Promise<?string>} */ |
| 62 this._requestContentPromise = null; | 60 this._requestContentPromise = null; |
| 63 /** @type {!Multimap<string, !Workspace.UISourceCode.LineMarker>} */ | 61 /** @type {!Multimap<string, !Workspace.UISourceCode.LineMarker>} */ |
| 64 this._decorations = new Multimap(); | 62 this._decorations = new Multimap(); |
| 65 | 63 |
| 66 /** @type {!Array.<!Workspace.Revision>} */ | 64 /** @type {!Array.<!Workspace.Revision>} */ |
| 67 this.history = []; | 65 this.history = []; |
| 68 | 66 |
| 69 /** @type {!Array<!Workspace.UISourceCode.Message>} */ | 67 /** @type {!Array<!Workspace.UISourceCode.Message>} */ |
| 70 this._messages = []; | 68 this._messages = []; |
| 69 | |
| 70 this._contentLoaded = false; | |
|
einbinder
2016/12/19 21:34:16
Make things explicit. Never undefined.
| |
| 71 /** @type {?string} */ | |
| 72 this._content = null; | |
| 73 this._forceLoadOnCheckContent = false; | |
| 74 this._checkingContent = false; | |
| 75 /** @type {?string} */ | |
| 76 this._lastAcceptedContent = null; | |
| 77 /** @type {?string} */ | |
| 78 this._workingCopy = null; | |
| 79 /** @type {?function() : string} */ | |
| 80 this._workingCopyGetter = null; | |
| 71 } | 81 } |
| 72 | 82 |
| 73 /** | 83 /** |
| 74 * @return {!Promise<?Workspace.UISourceCodeMetadata>} | 84 * @return {!Promise<?Workspace.UISourceCodeMetadata>} |
| 75 */ | 85 */ |
| 76 requestMetadata() { | 86 requestMetadata() { |
| 77 return this._project.requestMetadata(this); | 87 return this._project.requestMetadata(this); |
| 78 } | 88 } |
| 79 | 89 |
| 80 /** | 90 /** |
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 203 */ | 213 */ |
| 204 project() { | 214 project() { |
| 205 return this._project; | 215 return this._project; |
| 206 } | 216 } |
| 207 | 217 |
| 208 /** | 218 /** |
| 209 * @override | 219 * @override |
| 210 * @return {!Promise<?string>} | 220 * @return {!Promise<?string>} |
| 211 */ | 221 */ |
| 212 requestContent() { | 222 requestContent() { |
| 213 if (this._content || this._contentLoaded) | 223 if (!this._requestContentPromise) { |
|
einbinder
2016/12/19 21:34:16
Just return the same loading promise. Makes things
| |
| 214 return Promise.resolve(this._content); | 224 var fulfill; |
| 215 var promise = this._requestContentPromise; | 225 this._requestContentPromise = new Promise(x => fulfill = x); |
| 216 if (!promise) { | 226 this._project.requestFileContent(this, content => { |
| 217 promise = new Promise(fulfill => this._requestContentCallback = fulfill); | 227 this._contentLoaded = true; |
| 218 this._requestContentPromise = promise; | 228 this._content = content; |
| 219 this._project.requestFileContent(this, this._fireContentAvailable.bind(thi s)); | 229 fulfill(content); |
| 230 }); | |
| 220 } | 231 } |
| 221 return promise; | 232 return this._requestContentPromise; |
| 222 } | 233 } |
| 223 | 234 |
| 224 checkContentUpdated() { | 235 checkContentUpdated() { |
| 225 if (!this._contentLoaded && !this._forceLoadOnCheckContent) | 236 if (!this._contentLoaded && !this._forceLoadOnCheckContent) |
| 226 return; | 237 return; |
| 227 | 238 |
| 228 if (!this._project.canSetFileContent() || this._checkingContent) | 239 if (!this._project.canSetFileContent() || this._checkingContent) |
| 229 return; | 240 return; |
| 230 | 241 |
| 231 this._checkingContent = true; | 242 this._checkingContent = true; |
| 232 this._project.requestFileContent(this, contentLoaded.bind(this)); | 243 this._project.requestFileContent(this, contentLoaded.bind(this)); |
| 233 | 244 |
| 234 /** | 245 /** |
| 235 * @param {?string} updatedContent | 246 * @param {?string} updatedContent |
| 236 * @this {Workspace.UISourceCode} | 247 * @this {Workspace.UISourceCode} |
| 237 */ | 248 */ |
| 238 function contentLoaded(updatedContent) { | 249 function contentLoaded(updatedContent) { |
| 239 this._checkingContent = false; | 250 this._checkingContent = false; |
| 240 if (updatedContent === null) { | 251 if (updatedContent === null) { |
| 241 var workingCopy = this.workingCopy(); | 252 var workingCopy = this.workingCopy(); |
| 242 this._contentCommitted('', false); | 253 this._contentCommitted('', false); |
| 243 this.setWorkingCopy(workingCopy); | 254 this.setWorkingCopy(workingCopy); |
| 244 return; | 255 return; |
| 245 } | 256 } |
| 246 if (typeof this._lastAcceptedContent === 'string' && this._lastAcceptedCon tent === updatedContent) | 257 if (this._lastAcceptedContent === updatedContent) |
| 247 return; | 258 return; |
| 248 | 259 |
| 249 if (this._content === updatedContent) { | 260 if (this._content === updatedContent) { |
| 250 delete this._lastAcceptedContent; | 261 this._lastAcceptedContent = null; |
| 251 return; | 262 return; |
| 252 } | 263 } |
| 253 | 264 |
| 254 if (!this.isDirty() || this._workingCopy === updatedContent) { | 265 if (!this.isDirty() || this._workingCopy === updatedContent) { |
| 255 this._contentCommitted(updatedContent, false); | 266 this._contentCommitted(updatedContent, false); |
| 256 return; | 267 return; |
| 257 } | 268 } |
| 258 | 269 |
| 259 var shouldUpdate = | 270 var shouldUpdate = |
| 260 window.confirm(Common.UIString('This file was changed externally. Woul d you like to reload it?')); | 271 window.confirm(Common.UIString('This file was changed externally. Woul d you like to reload it?')); |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 290 Workspace.fileManager.close(this._url); | 301 Workspace.fileManager.close(this._url); |
| 291 } | 302 } |
| 292 this._contentCommitted(content, true); | 303 this._contentCommitted(content, true); |
| 293 } | 304 } |
| 294 | 305 |
| 295 /** | 306 /** |
| 296 * @param {string} content | 307 * @param {string} content |
| 297 * @param {boolean} committedByUser | 308 * @param {boolean} committedByUser |
| 298 */ | 309 */ |
| 299 _contentCommitted(content, committedByUser) { | 310 _contentCommitted(content, committedByUser) { |
| 300 delete this._lastAcceptedContent; | 311 this._lastAcceptedContent = null; |
| 301 this._content = content; | 312 this._content = content; |
| 302 this._contentLoaded = true; | 313 this._contentLoaded = true; |
| 314 this._requestContentPromise = Promise.resolve(/** @type {?string} */ (conten t)); | |
|
einbinder
2016/12/19 21:34:16
Closure gets confused with {?string} and {string}.
lushnikov
2016/12/19 23:32:13
let's clean the promise here to not do unnecessary
einbinder
2016/12/19 23:48:49
Done.
| |
| 303 | 315 |
| 304 var lastRevision = this.history.length ? this.history[this.history.length - 1] : null; | 316 var lastRevision = this.history.length ? this.history[this.history.length - 1] : null; |
| 305 if (!lastRevision || lastRevision._content !== this._content) { | 317 if (!lastRevision || lastRevision._content !== this._content) { |
| 306 var revision = new Workspace.Revision(this, this._content, new Date()); | 318 var revision = new Workspace.Revision(this, this._content, new Date()); |
| 307 this.history.push(revision); | 319 this.history.push(revision); |
| 308 } | 320 } |
| 309 | 321 |
| 310 this._innerResetWorkingCopy(); | 322 this._innerResetWorkingCopy(); |
| 311 this.dispatchEventToListeners( | 323 this.dispatchEventToListeners( |
| 312 Workspace.UISourceCode.Events.WorkingCopyCommitted, {uiSourceCode: this, content: content}); | 324 Workspace.UISourceCode.Events.WorkingCopyCommitted, {uiSourceCode: this, content: content}); |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 378 Host.userMetrics.actionTaken(Host.UserMetrics.Action.RevisionApplied); | 390 Host.userMetrics.actionTaken(Host.UserMetrics.Action.RevisionApplied); |
| 379 this.requestOriginalContent().then(revert.bind(this)); | 391 this.requestOriginalContent().then(revert.bind(this)); |
| 380 } | 392 } |
| 381 | 393 |
| 382 /** | 394 /** |
| 383 * @return {string} | 395 * @return {string} |
| 384 */ | 396 */ |
| 385 workingCopy() { | 397 workingCopy() { |
| 386 if (this._workingCopyGetter) { | 398 if (this._workingCopyGetter) { |
| 387 this._workingCopy = this._workingCopyGetter(); | 399 this._workingCopy = this._workingCopyGetter(); |
| 388 delete this._workingCopyGetter; | 400 this._workingCopyGetter = null; |
| 389 } | 401 } |
| 390 if (this.isDirty()) | 402 if (this.isDirty()) |
| 391 return this._workingCopy; | 403 return /** @type {string} */ (this._workingCopy); |
|
einbinder
2016/12/19 21:34:16
we know that workingCopyGetter is null, and it is
| |
| 392 return this._content; | 404 return this._content || ''; |
| 393 } | 405 } |
| 394 | 406 |
| 395 resetWorkingCopy() { | 407 resetWorkingCopy() { |
| 396 this._innerResetWorkingCopy(); | 408 this._innerResetWorkingCopy(); |
| 397 this._workingCopyChanged(); | 409 this._workingCopyChanged(); |
| 398 } | 410 } |
| 399 | 411 |
| 400 _innerResetWorkingCopy() { | 412 _innerResetWorkingCopy() { |
| 401 delete this._workingCopy; | 413 this._workingCopy = null; |
| 402 delete this._workingCopyGetter; | 414 this._workingCopyGetter = null; |
| 403 } | 415 } |
| 404 | 416 |
| 405 /** | 417 /** |
| 406 * @param {string} newWorkingCopy | 418 * @param {string} newWorkingCopy |
| 407 */ | 419 */ |
| 408 setWorkingCopy(newWorkingCopy) { | 420 setWorkingCopy(newWorkingCopy) { |
| 409 this._workingCopy = newWorkingCopy; | 421 this._workingCopy = newWorkingCopy; |
| 410 delete this._workingCopyGetter; | 422 this._workingCopyGetter = null; |
| 411 this._workingCopyChanged(); | 423 this._workingCopyChanged(); |
| 412 } | 424 } |
| 413 | 425 |
| 426 /** | |
| 427 * @param {function(): string } workingCopyGetter | |
| 428 */ | |
|
einbinder
2016/12/19 21:34:16
Typing!
| |
| 414 setWorkingCopyGetter(workingCopyGetter) { | 429 setWorkingCopyGetter(workingCopyGetter) { |
| 415 this._workingCopyGetter = workingCopyGetter; | 430 this._workingCopyGetter = workingCopyGetter; |
| 416 this._workingCopyChanged(); | 431 this._workingCopyChanged(); |
| 417 } | 432 } |
| 418 | 433 |
| 419 _workingCopyChanged() { | 434 _workingCopyChanged() { |
| 420 this._removeAllMessages(); | 435 this._removeAllMessages(); |
| 421 this.dispatchEventToListeners(Workspace.UISourceCode.Events.WorkingCopyChang ed, this); | 436 this.dispatchEventToListeners(Workspace.UISourceCode.Events.WorkingCopyChang ed, this); |
| 422 this._project.workspace().dispatchEventToListeners( | 437 this._project.workspace().dispatchEventToListeners( |
| 423 Workspace.Workspace.Events.WorkingCopyChanged, {uiSourceCode: this}); | 438 Workspace.Workspace.Events.WorkingCopyChanged, {uiSourceCode: this}); |
| 424 } | 439 } |
| 425 | 440 |
| 426 removeWorkingCopyGetter() { | 441 removeWorkingCopyGetter() { |
| 427 if (!this._workingCopyGetter) | 442 if (!this._workingCopyGetter) |
| 428 return; | 443 return; |
| 429 this._workingCopy = this._workingCopyGetter(); | 444 this._workingCopy = this._workingCopyGetter(); |
| 430 delete this._workingCopyGetter; | 445 this._workingCopyGetter = null; |
| 431 } | 446 } |
| 432 | 447 |
| 433 commitWorkingCopy() { | 448 commitWorkingCopy() { |
| 434 if (this.isDirty()) | 449 if (this.isDirty()) |
| 435 this._commitContent(this.workingCopy()); | 450 this._commitContent(this.workingCopy()); |
| 436 } | 451 } |
| 437 | 452 |
| 438 /** | 453 /** |
| 439 * @return {boolean} | 454 * @return {boolean} |
| 440 */ | 455 */ |
| 441 isDirty() { | 456 isDirty() { |
| 442 return typeof this._workingCopy !== 'undefined' || typeof this._workingCopyG etter !== 'undefined'; | 457 return this._workingCopy !== null || this._workingCopyGetter !== null; |
| 443 } | 458 } |
| 444 | 459 |
| 445 /** | 460 /** |
| 446 * @return {string} | 461 * @return {string} |
| 447 */ | 462 */ |
| 448 extension() { | 463 extension() { |
| 449 return Common.ParsedURL.extractExtension(this._name); | 464 return Common.ParsedURL.extractExtension(this._name); |
| 450 } | 465 } |
| 451 | 466 |
| 452 /** | 467 /** |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 475 | 490 |
| 476 /** | 491 /** |
| 477 * @param {string} content | 492 * @param {string} content |
| 478 */ | 493 */ |
| 479 function doSearch(content) { | 494 function doSearch(content) { |
| 480 callback(Common.ContentProvider.performSearchInContent(content, query, cas eSensitive, isRegex)); | 495 callback(Common.ContentProvider.performSearchInContent(content, query, cas eSensitive, isRegex)); |
| 481 } | 496 } |
| 482 } | 497 } |
| 483 | 498 |
| 484 /** | 499 /** |
| 485 * @param {?string} content | |
| 486 */ | |
| 487 _fireContentAvailable(content) { | |
|
einbinder
2016/12/19 21:34:16
This gets inlined.
| |
| 488 this._contentLoaded = true; | |
| 489 this._content = content; | |
| 490 | |
| 491 var callback = this._requestContentCallback; | |
| 492 this._requestContentCallback = null; | |
| 493 this._requestContentPromise = null; | |
| 494 | |
| 495 callback.call(null, content); | |
| 496 } | |
| 497 | |
| 498 /** | |
| 499 * @return {boolean} | 500 * @return {boolean} |
| 500 */ | 501 */ |
| 501 contentLoaded() { | 502 contentLoaded() { |
| 502 return this._contentLoaded; | 503 return this._contentLoaded; |
| 503 } | 504 } |
| 504 | 505 |
| 505 /** | 506 /** |
| 506 * @param {number} lineNumber | 507 * @param {number} lineNumber |
| 507 * @param {number=} columnNumber | 508 * @param {number=} columnNumber |
| 508 * @return {!Workspace.UILocation} | 509 * @return {!Workspace.UILocation} |
| (...skipping 392 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 901 Workspace.UISourceCodeMetadata = class { | 902 Workspace.UISourceCodeMetadata = class { |
| 902 /** | 903 /** |
| 903 * @param {?Date} modificationTime | 904 * @param {?Date} modificationTime |
| 904 * @param {?number} contentSize | 905 * @param {?number} contentSize |
| 905 */ | 906 */ |
| 906 constructor(modificationTime, contentSize) { | 907 constructor(modificationTime, contentSize) { |
| 907 this.modificationTime = modificationTime; | 908 this.modificationTime = modificationTime; |
| 908 this.contentSize = contentSize; | 909 this.contentSize = contentSize; |
| 909 } | 910 } |
| 910 }; | 911 }; |
| OLD | NEW |