| 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 |
| 11 * copyright notice, this list of conditions and the following disclaimer | 11 * copyright notice, this list of conditions and the following disclaimer |
| 12 * in the documentation and/or other materials provided with the | 12 * in the documentation and/or other materials provided with the |
| 13 * distribution. | 13 * distribution. |
| 14 * * Neither the name of Google Inc. nor the names of its | 14 * * Neither the name of Google Inc. nor the names of its |
| 15 * contributors may be used to endorse or promote products derived from | 15 * contributors may be used to endorse or promote products derived from |
| 16 * this software without specific prior written permission. | 16 * this software without specific prior written permission. |
| 17 * | 17 * |
| 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| 19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | 19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| 20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | 20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| 21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | 21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| 22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | 22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 29 */ | 29 */ |
| 30 | |
| 31 /** | 30 /** |
| 32 * @constructor | |
| 33 * @extends {WebInspector.Object} | |
| 34 * @implements {WebInspector.ContentProvider} | 31 * @implements {WebInspector.ContentProvider} |
| 35 * @param {!WebInspector.Project} project | 32 * @unrestricted |
| 36 * @param {string} url | |
| 37 * @param {!WebInspector.ResourceType} contentType | |
| 38 */ | 33 */ |
| 39 WebInspector.UISourceCode = function(project, url, contentType) | 34 WebInspector.UISourceCode = class extends WebInspector.Object { |
| 40 { | 35 /** |
| 36 * @param {!WebInspector.Project} project |
| 37 * @param {string} url |
| 38 * @param {!WebInspector.ResourceType} contentType |
| 39 */ |
| 40 constructor(project, url, contentType) { |
| 41 super(); |
| 41 this._project = project; | 42 this._project = project; |
| 42 this._url = url; | 43 this._url = url; |
| 43 | 44 |
| 44 var parsedURL = url.asParsedURL(); | 45 var parsedURL = url.asParsedURL(); |
| 45 if (parsedURL) { | 46 if (parsedURL) { |
| 46 this._origin = parsedURL.securityOrigin(); | 47 this._origin = parsedURL.securityOrigin(); |
| 47 this._parentURL = this._origin + parsedURL.folderPathComponents; | 48 this._parentURL = this._origin + parsedURL.folderPathComponents; |
| 48 this._name = parsedURL.lastPathComponent; | 49 this._name = parsedURL.lastPathComponent; |
| 49 if (parsedURL.queryParams) | 50 if (parsedURL.queryParams) |
| 50 this._name += "?" + parsedURL.queryParams; | 51 this._name += '?' + parsedURL.queryParams; |
| 51 } else { | 52 } else { |
| 52 this._origin = ""; | 53 this._origin = ''; |
| 53 this._parentURL = ""; | 54 this._parentURL = ''; |
| 54 this._name = url; | 55 this._name = url; |
| 55 } | 56 } |
| 56 | 57 |
| 57 this._contentType = contentType; | 58 this._contentType = contentType; |
| 58 /** @type {?function(?string)} */ | 59 /** @type {?function(?string)} */ |
| 59 this._requestContentCallback = null; | 60 this._requestContentCallback = null; |
| 60 /** @type {?Promise<?string>} */ | 61 /** @type {?Promise<?string>} */ |
| 61 this._requestContentPromise = null; | 62 this._requestContentPromise = null; |
| 62 /** @type {!Map<string, !Map<number, !WebInspector.UISourceCode.LineMarker>>
} */ | 63 /** @type {!Map<string, !Map<number, !WebInspector.UISourceCode.LineMarker>>
} */ |
| 63 this._lineDecorations = new Map(); | 64 this._lineDecorations = new Map(); |
| 64 | 65 |
| 65 /** @type {!Array.<!WebInspector.Revision>} */ | 66 /** @type {!Array.<!WebInspector.Revision>} */ |
| 66 this.history = []; | 67 this.history = []; |
| 67 | 68 |
| 68 /** @type {!Array<!WebInspector.UISourceCode.Message>} */ | 69 /** @type {!Array<!WebInspector.UISourceCode.Message>} */ |
| 69 this._messages = []; | 70 this._messages = []; |
| 70 }; | 71 } |
| 71 | 72 |
| 72 /** @enum {symbol} */ | 73 /** |
| 73 WebInspector.UISourceCode.Events = { | 74 * @return {!Promise<?WebInspector.UISourceCodeMetadata>} |
| 74 WorkingCopyChanged: Symbol("WorkingCopyChanged"), | 75 */ |
| 75 WorkingCopyCommitted: Symbol("WorkingCopyCommitted"), | 76 requestMetadata() { |
| 76 TitleChanged: Symbol("TitleChanged"), | 77 return this._project.requestMetadata(this); |
| 77 SourceMappingChanged: Symbol("SourceMappingChanged"), | 78 } |
| 78 MessageAdded: Symbol("MessageAdded"), | 79 |
| 79 MessageRemoved: Symbol("MessageRemoved"), | 80 /** |
| 80 LineDecorationAdded: Symbol("LineDecorationAdded"), | 81 * @return {string} |
| 81 LineDecorationRemoved: Symbol("LineDecorationRemoved") | 82 */ |
| 82 }; | 83 name() { |
| 83 | 84 return this._name; |
| 84 WebInspector.UISourceCode.prototype = { | 85 } |
| 86 |
| 87 /** |
| 88 * @return {string} |
| 89 */ |
| 90 url() { |
| 91 return this._url; |
| 92 } |
| 93 |
| 94 /** |
| 95 * @return {string} |
| 96 */ |
| 97 parentURL() { |
| 98 return this._parentURL; |
| 99 } |
| 100 |
| 101 /** |
| 102 * @return {string} |
| 103 */ |
| 104 origin() { |
| 105 return this._origin; |
| 106 } |
| 107 |
| 108 /** |
| 109 * @return {string} |
| 110 */ |
| 111 fullDisplayName() { |
| 112 var parentPath = this._parentURL.replace(/^(?:https?|file)\:\/\//, ''); |
| 113 try { |
| 114 parentPath = decodeURI(parentPath); |
| 115 } catch (e) { |
| 116 } |
| 117 return parentPath + '/' + this.displayName(true); |
| 118 } |
| 119 |
| 120 /** |
| 121 * @param {boolean=} skipTrim |
| 122 * @return {string} |
| 123 */ |
| 124 displayName(skipTrim) { |
| 125 if (!this._name) |
| 126 return WebInspector.UIString('(index)'); |
| 127 var name = this._name; |
| 128 try { |
| 129 name = decodeURI(name); |
| 130 } catch (e) { |
| 131 } |
| 132 return skipTrim ? name : name.trimEnd(100); |
| 133 } |
| 134 |
| 135 /** |
| 136 * @return {boolean} |
| 137 */ |
| 138 isFromServiceProject() { |
| 139 return WebInspector.Project.isServiceProject(this._project); |
| 140 } |
| 141 |
| 142 /** |
| 143 * @return {boolean} |
| 144 */ |
| 145 canRename() { |
| 146 return this._project.canRename(); |
| 147 } |
| 148 |
| 149 /** |
| 150 * @param {string} newName |
| 151 * @param {function(boolean)} callback |
| 152 */ |
| 153 rename(newName, callback) { |
| 154 this._project.rename(this, newName, innerCallback.bind(this)); |
| 155 |
| 85 /** | 156 /** |
| 86 * @return {!Promise<?WebInspector.UISourceCodeMetadata>} | 157 * @param {boolean} success |
| 158 * @param {string=} newName |
| 159 * @param {string=} newURL |
| 160 * @param {!WebInspector.ResourceType=} newContentType |
| 161 * @this {WebInspector.UISourceCode} |
| 87 */ | 162 */ |
| 88 requestMetadata: function() | 163 function innerCallback(success, newName, newURL, newContentType) { |
| 89 { | 164 if (success) |
| 90 return this._project.requestMetadata(this); | 165 this._updateName( |
| 91 }, | 166 /** @type {string} */ (newName), /** @type {string} */ (newURL), |
| 167 /** @type {!WebInspector.ResourceType} */ (newContentType)); |
| 168 callback(success); |
| 169 } |
| 170 } |
| 171 |
| 172 remove() { |
| 173 this._project.deleteFile(this.url()); |
| 174 } |
| 175 |
| 176 /** |
| 177 * @param {string} name |
| 178 * @param {string} url |
| 179 * @param {!WebInspector.ResourceType=} contentType |
| 180 */ |
| 181 _updateName(name, url, contentType) { |
| 182 var oldURL = this.url(); |
| 183 this._url = this._url.substring(0, this._url.length - this._name.length) + n
ame; |
| 184 this._name = name; |
| 185 if (url) |
| 186 this._url = url; |
| 187 if (contentType) |
| 188 this._contentType = contentType; |
| 189 this.dispatchEventToListeners(WebInspector.UISourceCode.Events.TitleChanged,
oldURL); |
| 190 } |
| 191 |
| 192 /** |
| 193 * @override |
| 194 * @return {string} |
| 195 */ |
| 196 contentURL() { |
| 197 return this.url(); |
| 198 } |
| 199 |
| 200 /** |
| 201 * @override |
| 202 * @return {!WebInspector.ResourceType} |
| 203 */ |
| 204 contentType() { |
| 205 return this._contentType; |
| 206 } |
| 207 |
| 208 /** |
| 209 * @return {!WebInspector.Project} |
| 210 */ |
| 211 project() { |
| 212 return this._project; |
| 213 } |
| 214 |
| 215 /** |
| 216 * @override |
| 217 * @return {!Promise<?string>} |
| 218 */ |
| 219 requestContent() { |
| 220 if (this._content || this._contentLoaded) |
| 221 return Promise.resolve(this._content); |
| 222 var promise = this._requestContentPromise; |
| 223 if (!promise) { |
| 224 promise = new Promise(fulfill => this._requestContentCallback = fulfill); |
| 225 this._requestContentPromise = promise; |
| 226 this._project.requestFileContent(this, this._fireContentAvailable.bind(thi
s)); |
| 227 } |
| 228 return promise; |
| 229 } |
| 230 |
| 231 /** |
| 232 * @param {function()} callback |
| 233 */ |
| 234 _pushCheckContentUpdatedCallback(callback) { |
| 235 if (!this._checkContentUpdatedCallbacks) |
| 236 this._checkContentUpdatedCallbacks = []; |
| 237 this._checkContentUpdatedCallbacks.push(callback); |
| 238 } |
| 239 |
| 240 _terminateContentCheck() { |
| 241 delete this._checkingContent; |
| 242 if (this._checkContentUpdatedCallbacks) { |
| 243 this._checkContentUpdatedCallbacks.forEach(function(callback) { |
| 244 callback(); |
| 245 }); |
| 246 delete this._checkContentUpdatedCallbacks; |
| 247 } |
| 248 } |
| 249 |
| 250 /** |
| 251 * @param {boolean=} forceLoad |
| 252 * @param {function()=} callback |
| 253 */ |
| 254 checkContentUpdated(forceLoad, callback) { |
| 255 callback = callback || function() {}; |
| 256 forceLoad = forceLoad || this._forceLoadOnCheckContent; |
| 257 if (!this.contentLoaded() && !forceLoad) { |
| 258 callback(); |
| 259 return; |
| 260 } |
| 261 |
| 262 if (!this._project.canSetFileContent()) { |
| 263 callback(); |
| 264 return; |
| 265 } |
| 266 this._pushCheckContentUpdatedCallback(callback); |
| 267 |
| 268 if (this._checkingContent) |
| 269 return; |
| 270 |
| 271 this._checkingContent = true; |
| 272 this._project.requestFileContent(this, contentLoaded.bind(this)); |
| 92 | 273 |
| 93 /** | 274 /** |
| 94 * @return {string} | 275 * @param {?string} updatedContent |
| 276 * @this {WebInspector.UISourceCode} |
| 95 */ | 277 */ |
| 96 name: function() | 278 function contentLoaded(updatedContent) { |
| 97 { | 279 if (updatedContent === null) { |
| 98 return this._name; | 280 var workingCopy = this.workingCopy(); |
| 99 }, | 281 this._contentCommitted('', false); |
| 282 this.setWorkingCopy(workingCopy); |
| 283 this._terminateContentCheck(); |
| 284 return; |
| 285 } |
| 286 if (typeof this._lastAcceptedContent === 'string' && this._lastAcceptedCon
tent === updatedContent) { |
| 287 this._terminateContentCheck(); |
| 288 return; |
| 289 } |
| 290 |
| 291 if (this._content === updatedContent) { |
| 292 delete this._lastAcceptedContent; |
| 293 this._terminateContentCheck(); |
| 294 return; |
| 295 } |
| 296 |
| 297 if (!this.isDirty() || this._workingCopy === updatedContent) { |
| 298 this._contentCommitted(updatedContent, false); |
| 299 this._terminateContentCheck(); |
| 300 return; |
| 301 } |
| 302 |
| 303 var shouldUpdate = |
| 304 window.confirm(WebInspector.UIString('This file was changed externally
. Would you like to reload it?')); |
| 305 if (shouldUpdate) |
| 306 this._contentCommitted(updatedContent, false); |
| 307 else |
| 308 this._lastAcceptedContent = updatedContent; |
| 309 this._terminateContentCheck(); |
| 310 } |
| 311 } |
| 312 |
| 313 forceLoadOnCheckContent() { |
| 314 this._forceLoadOnCheckContent = true; |
| 315 } |
| 316 |
| 317 /** |
| 318 * @return {!Promise<?string>} |
| 319 */ |
| 320 requestOriginalContent() { |
| 321 var callback; |
| 322 var promise = new Promise(fulfill => callback = fulfill); |
| 323 this._project.requestFileContent(this, callback); |
| 324 return promise; |
| 325 } |
| 326 |
| 327 /** |
| 328 * @param {string} content |
| 329 */ |
| 330 _commitContent(content) { |
| 331 if (this._project.canSetFileContent()) { |
| 332 this._project.setFileContent(this, content, function() {}); |
| 333 } else if (this._url && WebInspector.fileManager.isURLSaved(this._url)) { |
| 334 WebInspector.fileManager.save(this._url, content, false, function() {}); |
| 335 WebInspector.fileManager.close(this._url); |
| 336 } |
| 337 this._contentCommitted(content, true); |
| 338 } |
| 339 |
| 340 /** |
| 341 * @param {string} content |
| 342 * @param {boolean} committedByUser |
| 343 */ |
| 344 _contentCommitted(content, committedByUser) { |
| 345 delete this._lastAcceptedContent; |
| 346 this._content = content; |
| 347 this._contentLoaded = true; |
| 348 |
| 349 var lastRevision = this.history.length ? this.history[this.history.length -
1] : null; |
| 350 if (!lastRevision || lastRevision._content !== this._content) { |
| 351 var revision = new WebInspector.Revision(this, this._content, new Date()); |
| 352 this.history.push(revision); |
| 353 } |
| 354 |
| 355 this._innerResetWorkingCopy(); |
| 356 this.dispatchEventToListeners(WebInspector.UISourceCode.Events.WorkingCopyCo
mmitted, {content: content}); |
| 357 this._project.workspace().dispatchEventToListeners( |
| 358 WebInspector.Workspace.Events.WorkingCopyCommitted, {uiSourceCode: this,
content: content}); |
| 359 if (committedByUser) |
| 360 this._project.workspace().dispatchEventToListeners( |
| 361 WebInspector.Workspace.Events.WorkingCopyCommittedByUser, {uiSourceCod
e: this, content: content}); |
| 362 } |
| 363 |
| 364 saveAs() { |
| 365 WebInspector.fileManager.save(this._url, this.workingCopy(), true, callback.
bind(this)); |
| 366 WebInspector.fileManager.close(this._url); |
| 100 | 367 |
| 101 /** | 368 /** |
| 102 * @return {string} | 369 * @param {boolean} accepted |
| 370 * @this {WebInspector.UISourceCode} |
| 103 */ | 371 */ |
| 104 url: function() | 372 function callback(accepted) { |
| 105 { | 373 if (accepted) |
| 106 return this._url; | 374 this._contentCommitted(this.workingCopy(), true); |
| 107 }, | 375 } |
| 108 | 376 } |
| 377 |
| 378 /** |
| 379 * @param {string} content |
| 380 */ |
| 381 addRevision(content) { |
| 382 this._commitContent(content); |
| 383 } |
| 384 |
| 385 /** |
| 386 * @return {!Promise} |
| 387 */ |
| 388 revertToOriginal() { |
| 109 /** | 389 /** |
| 110 * @return {string} | 390 * @this {WebInspector.UISourceCode} |
| 391 * @param {?string} content |
| 111 */ | 392 */ |
| 112 parentURL: function() | 393 function callback(content) { |
| 113 { | 394 if (typeof content !== 'string') |
| 114 return this._parentURL; | 395 return; |
| 115 }, | 396 |
| 116 | 397 this.addRevision(content); |
| 398 } |
| 399 |
| 400 WebInspector.userMetrics.actionTaken(WebInspector.UserMetrics.Action.Revisio
nApplied); |
| 401 return this.requestOriginalContent().then(callback.bind(this)); |
| 402 } |
| 403 |
| 404 /** |
| 405 * @param {function(!WebInspector.UISourceCode)} callback |
| 406 */ |
| 407 revertAndClearHistory(callback) { |
| 117 /** | 408 /** |
| 118 * @return {string} | 409 * @this {WebInspector.UISourceCode} |
| 410 * @param {?string} content |
| 119 */ | 411 */ |
| 120 origin: function() | 412 function revert(content) { |
| 121 { | 413 if (typeof content !== 'string') |
| 122 return this._origin; | 414 return; |
| 123 }, | 415 |
| 124 | 416 this.addRevision(content); |
| 125 /** | 417 this.history = []; |
| 126 * @return {string} | 418 callback(this); |
| 127 */ | 419 } |
| 128 fullDisplayName: function() | 420 |
| 129 { | 421 WebInspector.userMetrics.actionTaken(WebInspector.UserMetrics.Action.Revisio
nApplied); |
| 130 var parentPath = this._parentURL.replace(/^(?:https?|file)\:\/\//, ""); | 422 this.requestOriginalContent().then(revert.bind(this)); |
| 131 try { | 423 } |
| 132 parentPath = decodeURI(parentPath); | 424 |
| 133 } catch (e) { | 425 /** |
| 134 } | 426 * @return {string} |
| 135 return parentPath + "/" + this.displayName(true); | 427 */ |
| 136 }, | 428 workingCopy() { |
| 137 | 429 if (this._workingCopyGetter) { |
| 138 /** | 430 this._workingCopy = this._workingCopyGetter(); |
| 139 * @param {boolean=} skipTrim | 431 delete this._workingCopyGetter; |
| 140 * @return {string} | 432 } |
| 141 */ | 433 if (this.isDirty()) |
| 142 displayName: function(skipTrim) | 434 return this._workingCopy; |
| 143 { | 435 return this._content; |
| 144 if (!this._name) | 436 } |
| 145 return WebInspector.UIString("(index)"); | 437 |
| 146 var name = this._name; | 438 resetWorkingCopy() { |
| 147 try { | 439 this._innerResetWorkingCopy(); |
| 148 name = decodeURI(name); | 440 this.dispatchEventToListeners(WebInspector.UISourceCode.Events.WorkingCopyCh
anged); |
| 149 } catch (e) { | 441 } |
| 150 } | 442 |
| 151 return skipTrim ? name : name.trimEnd(100); | 443 _innerResetWorkingCopy() { |
| 152 }, | 444 delete this._workingCopy; |
| 153 | 445 delete this._workingCopyGetter; |
| 154 /** | 446 } |
| 155 * @return {boolean} | 447 |
| 156 */ | 448 /** |
| 157 isFromServiceProject: function() | 449 * @param {string} newWorkingCopy |
| 158 { | 450 */ |
| 159 return WebInspector.Project.isServiceProject(this._project); | 451 setWorkingCopy(newWorkingCopy) { |
| 160 }, | 452 this._workingCopy = newWorkingCopy; |
| 161 | 453 delete this._workingCopyGetter; |
| 162 /** | 454 this.dispatchEventToListeners(WebInspector.UISourceCode.Events.WorkingCopyCh
anged); |
| 163 * @return {boolean} | 455 this._project.workspace().dispatchEventToListeners( |
| 164 */ | 456 WebInspector.Workspace.Events.WorkingCopyChanged, {uiSourceCode: this}); |
| 165 canRename: function() | 457 } |
| 166 { | 458 |
| 167 return this._project.canRename(); | 459 setWorkingCopyGetter(workingCopyGetter) { |
| 168 }, | 460 this._workingCopyGetter = workingCopyGetter; |
| 169 | 461 this.dispatchEventToListeners(WebInspector.UISourceCode.Events.WorkingCopyCh
anged); |
| 170 /** | 462 this._project.workspace().dispatchEventToListeners( |
| 171 * @param {string} newName | 463 WebInspector.Workspace.Events.WorkingCopyChanged, {uiSourceCode: this}); |
| 172 * @param {function(boolean)} callback | 464 } |
| 173 */ | 465 |
| 174 rename: function(newName, callback) | 466 removeWorkingCopyGetter() { |
| 175 { | 467 if (!this._workingCopyGetter) |
| 176 this._project.rename(this, newName, innerCallback.bind(this)); | 468 return; |
| 177 | 469 this._workingCopy = this._workingCopyGetter(); |
| 178 /** | 470 delete this._workingCopyGetter; |
| 179 * @param {boolean} success | 471 } |
| 180 * @param {string=} newName | 472 |
| 181 * @param {string=} newURL | 473 commitWorkingCopy() { |
| 182 * @param {!WebInspector.ResourceType=} newContentType | 474 if (this.isDirty()) |
| 183 * @this {WebInspector.UISourceCode} | 475 this._commitContent(this.workingCopy()); |
| 184 */ | 476 } |
| 185 function innerCallback(success, newName, newURL, newContentType) | 477 |
| 186 { | 478 /** |
| 187 if (success) | 479 * @return {boolean} |
| 188 this._updateName(/** @type {string} */ (newName), /** @type {str
ing} */ (newURL), /** @type {!WebInspector.ResourceType} */ (newContentType)); | 480 */ |
| 189 callback(success); | 481 isDirty() { |
| 190 } | 482 return typeof this._workingCopy !== 'undefined' || typeof this._workingCopyG
etter !== 'undefined'; |
| 191 }, | 483 } |
| 192 | 484 |
| 193 remove: function() | 485 /** |
| 194 { | 486 * @return {string} |
| 195 this._project.deleteFile(this.url()); | 487 */ |
| 196 }, | 488 extension() { |
| 197 | 489 return WebInspector.ParsedURL.extractExtension(this._name); |
| 198 /** | 490 } |
| 199 * @param {string} name | 491 |
| 200 * @param {string} url | 492 /** |
| 201 * @param {!WebInspector.ResourceType=} contentType | 493 * @return {?string} |
| 202 */ | 494 */ |
| 203 _updateName: function(name, url, contentType) | 495 content() { |
| 204 { | 496 return this._content; |
| 205 var oldURL = this.url(); | 497 } |
| 206 this._url = this._url.substring(0, this._url.length - this._name.length)
+ name; | 498 |
| 207 this._name = name; | 499 /** |
| 208 if (url) | 500 * @override |
| 209 this._url = url; | 501 * @param {string} query |
| 210 if (contentType) | 502 * @param {boolean} caseSensitive |
| 211 this._contentType = contentType; | 503 * @param {boolean} isRegex |
| 212 this.dispatchEventToListeners(WebInspector.UISourceCode.Events.TitleChan
ged, oldURL); | 504 * @param {function(!Array.<!WebInspector.ContentProvider.SearchMatch>)} callb
ack |
| 213 }, | 505 */ |
| 214 | 506 searchInContent(query, caseSensitive, isRegex, callback) { |
| 215 /** | 507 var content = this.content(); |
| 216 * @override | 508 if (!content) { |
| 217 * @return {string} | 509 this._project.searchInFileContent(this, query, caseSensitive, isRegex, cal
lback); |
| 218 */ | 510 return; |
| 219 contentURL: function() | 511 } |
| 220 { | 512 |
| 221 return this.url(); | 513 // searchInContent should call back later. |
| 222 }, | 514 setTimeout(doSearch.bind(null, content), 0); |
| 223 | |
| 224 /** | |
| 225 * @override | |
| 226 * @return {!WebInspector.ResourceType} | |
| 227 */ | |
| 228 contentType: function() | |
| 229 { | |
| 230 return this._contentType; | |
| 231 }, | |
| 232 | |
| 233 /** | |
| 234 * @return {!WebInspector.Project} | |
| 235 */ | |
| 236 project: function() | |
| 237 { | |
| 238 return this._project; | |
| 239 }, | |
| 240 | |
| 241 /** | |
| 242 * @override | |
| 243 * @return {!Promise<?string>} | |
| 244 */ | |
| 245 requestContent: function() | |
| 246 { | |
| 247 if (this._content || this._contentLoaded) | |
| 248 return Promise.resolve(this._content); | |
| 249 var promise = this._requestContentPromise; | |
| 250 if (!promise) { | |
| 251 promise = new Promise(fulfill => this._requestContentCallback = fulf
ill); | |
| 252 this._requestContentPromise = promise; | |
| 253 this._project.requestFileContent(this, this._fireContentAvailable.bi
nd(this)); | |
| 254 } | |
| 255 return promise; | |
| 256 }, | |
| 257 | |
| 258 /** | |
| 259 * @param {function()} callback | |
| 260 */ | |
| 261 _pushCheckContentUpdatedCallback: function(callback) | |
| 262 { | |
| 263 if (!this._checkContentUpdatedCallbacks) | |
| 264 this._checkContentUpdatedCallbacks = []; | |
| 265 this._checkContentUpdatedCallbacks.push(callback); | |
| 266 }, | |
| 267 | |
| 268 _terminateContentCheck: function() | |
| 269 { | |
| 270 delete this._checkingContent; | |
| 271 if (this._checkContentUpdatedCallbacks) { | |
| 272 this._checkContentUpdatedCallbacks.forEach(function(callback) { call
back(); }); | |
| 273 delete this._checkContentUpdatedCallbacks; | |
| 274 } | |
| 275 }, | |
| 276 | |
| 277 /** | |
| 278 * @param {boolean=} forceLoad | |
| 279 * @param {function()=} callback | |
| 280 */ | |
| 281 checkContentUpdated: function(forceLoad, callback) | |
| 282 { | |
| 283 callback = callback || function() {}; | |
| 284 forceLoad = forceLoad || this._forceLoadOnCheckContent; | |
| 285 if (!this.contentLoaded() && !forceLoad) { | |
| 286 callback(); | |
| 287 return; | |
| 288 } | |
| 289 | |
| 290 if (!this._project.canSetFileContent()) { | |
| 291 callback(); | |
| 292 return; | |
| 293 } | |
| 294 this._pushCheckContentUpdatedCallback(callback); | |
| 295 | |
| 296 if (this._checkingContent) | |
| 297 return; | |
| 298 | |
| 299 this._checkingContent = true; | |
| 300 this._project.requestFileContent(this, contentLoaded.bind(this)); | |
| 301 | |
| 302 /** | |
| 303 * @param {?string} updatedContent | |
| 304 * @this {WebInspector.UISourceCode} | |
| 305 */ | |
| 306 function contentLoaded(updatedContent) | |
| 307 { | |
| 308 if (updatedContent === null) { | |
| 309 var workingCopy = this.workingCopy(); | |
| 310 this._contentCommitted("", false); | |
| 311 this.setWorkingCopy(workingCopy); | |
| 312 this._terminateContentCheck(); | |
| 313 return; | |
| 314 } | |
| 315 if (typeof this._lastAcceptedContent === "string" && this._lastAccep
tedContent === updatedContent) { | |
| 316 this._terminateContentCheck(); | |
| 317 return; | |
| 318 } | |
| 319 | |
| 320 if (this._content === updatedContent) { | |
| 321 delete this._lastAcceptedContent; | |
| 322 this._terminateContentCheck(); | |
| 323 return; | |
| 324 } | |
| 325 | |
| 326 if (!this.isDirty() || this._workingCopy === updatedContent) { | |
| 327 this._contentCommitted(updatedContent, false); | |
| 328 this._terminateContentCheck(); | |
| 329 return; | |
| 330 } | |
| 331 | |
| 332 var shouldUpdate = window.confirm(WebInspector.UIString("This file w
as changed externally. Would you like to reload it?")); | |
| 333 if (shouldUpdate) | |
| 334 this._contentCommitted(updatedContent, false); | |
| 335 else | |
| 336 this._lastAcceptedContent = updatedContent; | |
| 337 this._terminateContentCheck(); | |
| 338 } | |
| 339 }, | |
| 340 | |
| 341 forceLoadOnCheckContent: function() | |
| 342 { | |
| 343 this._forceLoadOnCheckContent = true; | |
| 344 }, | |
| 345 | |
| 346 /** | |
| 347 * @return {!Promise<?string>} | |
| 348 */ | |
| 349 requestOriginalContent: function() | |
| 350 { | |
| 351 var callback; | |
| 352 var promise = new Promise(fulfill => callback = fulfill); | |
| 353 this._project.requestFileContent(this, callback); | |
| 354 return promise; | |
| 355 }, | |
| 356 | 515 |
| 357 /** | 516 /** |
| 358 * @param {string} content | 517 * @param {string} content |
| 359 */ | 518 */ |
| 360 _commitContent: function(content) | 519 function doSearch(content) { |
| 361 { | 520 callback(WebInspector.ContentProvider.performSearchInContent(content, quer
y, caseSensitive, isRegex)); |
| 362 if (this._project.canSetFileContent()) { | 521 } |
| 363 this._project.setFileContent(this, content, function() { }); | 522 } |
| 364 } else if (this._url && WebInspector.fileManager.isURLSaved(this._url))
{ | 523 |
| 365 WebInspector.fileManager.save(this._url, content, false, function()
{ }); | 524 /** |
| 366 WebInspector.fileManager.close(this._url); | 525 * @param {?string} content |
| 367 } | 526 */ |
| 368 this._contentCommitted(content, true); | 527 _fireContentAvailable(content) { |
| 369 }, | 528 this._contentLoaded = true; |
| 370 | 529 this._content = content; |
| 371 /** | 530 |
| 372 * @param {string} content | 531 var callback = this._requestContentCallback; |
| 373 * @param {boolean} committedByUser | 532 this._requestContentCallback = null; |
| 374 */ | 533 this._requestContentPromise = null; |
| 375 _contentCommitted: function(content, committedByUser) | 534 |
| 376 { | 535 callback.call(null, content); |
| 377 delete this._lastAcceptedContent; | 536 } |
| 378 this._content = content; | 537 |
| 379 this._contentLoaded = true; | 538 /** |
| 380 | 539 * @return {boolean} |
| 381 var lastRevision = this.history.length ? this.history[this.history.lengt
h - 1] : null; | 540 */ |
| 382 if (!lastRevision || lastRevision._content !== this._content) { | 541 contentLoaded() { |
| 383 var revision = new WebInspector.Revision(this, this._content, new Da
te()); | 542 return this._contentLoaded; |
| 384 this.history.push(revision); | 543 } |
| 385 } | 544 |
| 386 | 545 /** |
| 387 this._innerResetWorkingCopy(); | 546 * @param {number} lineNumber |
| 388 this.dispatchEventToListeners(WebInspector.UISourceCode.Events.WorkingCo
pyCommitted, { content: content }); | 547 * @param {number=} columnNumber |
| 389 this._project.workspace().dispatchEventToListeners(WebInspector.Workspac
e.Events.WorkingCopyCommitted, { uiSourceCode: this, content: content }); | 548 * @return {!WebInspector.UILocation} |
| 390 if (committedByUser) | 549 */ |
| 391 this._project.workspace().dispatchEventToListeners(WebInspector.Work
space.Events.WorkingCopyCommittedByUser, { uiSourceCode: this, content: content
}); | 550 uiLocation(lineNumber, columnNumber) { |
| 392 }, | 551 if (typeof columnNumber === 'undefined') |
| 393 | 552 columnNumber = 0; |
| 394 saveAs: function() | 553 return new WebInspector.UILocation(this, lineNumber, columnNumber); |
| 395 { | 554 } |
| 396 WebInspector.fileManager.save(this._url, this.workingCopy(), true, callb
ack.bind(this)); | 555 |
| 397 WebInspector.fileManager.close(this._url); | 556 /** |
| 398 | 557 * @return {!Array<!WebInspector.UISourceCode.Message>} |
| 399 /** | 558 */ |
| 400 * @param {boolean} accepted | 559 messages() { |
| 401 * @this {WebInspector.UISourceCode} | 560 return this._messages.slice(); |
| 402 */ | 561 } |
| 403 function callback(accepted) | 562 |
| 404 { | 563 /** |
| 405 if (accepted) | 564 * @param {!WebInspector.UISourceCode.Message.Level} level |
| 406 this._contentCommitted(this.workingCopy(), true); | 565 * @param {string} text |
| 407 } | 566 * @param {number} lineNumber |
| 408 }, | 567 * @param {number=} columnNumber |
| 409 | 568 * @return {!WebInspector.UISourceCode.Message} message |
| 410 /** | 569 */ |
| 411 * @param {string} content | 570 addLineMessage(level, text, lineNumber, columnNumber) { |
| 412 */ | 571 return this.addMessage( |
| 413 addRevision: function(content) | 572 level, text, new WebInspector.TextRange(lineNumber, columnNumber || 0, l
ineNumber, columnNumber || 0)); |
| 414 { | 573 } |
| 415 this._commitContent(content); | 574 |
| 416 }, | 575 /** |
| 417 | 576 * @param {!WebInspector.UISourceCode.Message.Level} level |
| 418 /** | 577 * @param {string} text |
| 419 * @return {!Promise} | 578 * @param {!WebInspector.TextRange} range |
| 420 */ | 579 * @return {!WebInspector.UISourceCode.Message} message |
| 421 revertToOriginal: function() | 580 */ |
| 422 { | 581 addMessage(level, text, range) { |
| 423 /** | 582 var message = new WebInspector.UISourceCode.Message(this, level, text, range
); |
| 424 * @this {WebInspector.UISourceCode} | 583 this._messages.push(message); |
| 425 * @param {?string} content | 584 this.dispatchEventToListeners(WebInspector.UISourceCode.Events.MessageAdded,
message); |
| 426 */ | 585 return message; |
| 427 function callback(content) | 586 } |
| 428 { | 587 |
| 429 if (typeof content !== "string") | 588 /** |
| 430 return; | 589 * @param {!WebInspector.UISourceCode.Message} message |
| 431 | 590 */ |
| 432 this.addRevision(content); | 591 removeMessage(message) { |
| 433 } | 592 if (this._messages.remove(message)) |
| 434 | 593 this.dispatchEventToListeners(WebInspector.UISourceCode.Events.MessageRemo
ved, message); |
| 435 WebInspector.userMetrics.actionTaken(WebInspector.UserMetrics.Action.Rev
isionApplied); | 594 } |
| 436 return this.requestOriginalContent().then(callback.bind(this)); | 595 |
| 437 }, | 596 removeAllMessages() { |
| 438 | 597 var messages = this._messages; |
| 439 /** | 598 this._messages = []; |
| 440 * @param {function(!WebInspector.UISourceCode)} callback | 599 for (var message of messages) |
| 441 */ | 600 this.dispatchEventToListeners(WebInspector.UISourceCode.Events.MessageRemo
ved, message); |
| 442 revertAndClearHistory: function(callback) | 601 } |
| 443 { | 602 |
| 444 /** | 603 /** |
| 445 * @this {WebInspector.UISourceCode} | 604 * @param {number} lineNumber |
| 446 * @param {?string} content | 605 * @param {string} type |
| 447 */ | 606 * @param {?} data |
| 448 function revert(content) | 607 */ |
| 449 { | 608 addLineDecoration(lineNumber, type, data) { |
| 450 if (typeof content !== "string") | 609 var markers = this._lineDecorations.get(type); |
| 451 return; | 610 if (!markers) { |
| 452 | 611 markers = new Map(); |
| 453 this.addRevision(content); | 612 this._lineDecorations.set(type, markers); |
| 454 this.history = []; | 613 } |
| 455 callback(this); | 614 var marker = new WebInspector.UISourceCode.LineMarker(lineNumber, type, data
); |
| 456 } | 615 markers.set(lineNumber, marker); |
| 457 | 616 this.dispatchEventToListeners(WebInspector.UISourceCode.Events.LineDecoratio
nAdded, marker); |
| 458 WebInspector.userMetrics.actionTaken(WebInspector.UserMetrics.Action.Rev
isionApplied); | 617 } |
| 459 this.requestOriginalContent().then(revert.bind(this)); | 618 |
| 460 }, | 619 /** |
| 461 | 620 * @param {number} lineNumber |
| 462 /** | 621 * @param {string} type |
| 463 * @return {string} | 622 */ |
| 464 */ | 623 removeLineDecoration(lineNumber, type) { |
| 465 workingCopy: function() | 624 var markers = this._lineDecorations.get(type); |
| 466 { | 625 if (!markers) |
| 467 if (this._workingCopyGetter) { | 626 return; |
| 468 this._workingCopy = this._workingCopyGetter(); | 627 var marker = markers.get(lineNumber); |
| 469 delete this._workingCopyGetter; | 628 if (!marker) |
| 470 } | 629 return; |
| 471 if (this.isDirty()) | 630 markers.delete(lineNumber); |
| 472 return this._workingCopy; | 631 this.dispatchEventToListeners(WebInspector.UISourceCode.Events.LineDecoratio
nRemoved, marker); |
| 473 return this._content; | 632 if (!markers.size) |
| 474 }, | 633 this._lineDecorations.delete(type); |
| 475 | 634 } |
| 476 resetWorkingCopy: function() | 635 |
| 477 { | 636 /** |
| 478 this._innerResetWorkingCopy(); | 637 * @param {string} type |
| 479 this.dispatchEventToListeners(WebInspector.UISourceCode.Events.WorkingCo
pyChanged); | 638 */ |
| 480 }, | 639 removeAllLineDecorations(type) { |
| 481 | 640 var markers = this._lineDecorations.get(type); |
| 482 _innerResetWorkingCopy: function() | 641 if (!markers) |
| 483 { | 642 return; |
| 484 delete this._workingCopy; | 643 this._lineDecorations.delete(type); |
| 485 delete this._workingCopyGetter; | 644 markers.forEach(marker => { |
| 486 }, | 645 this.dispatchEventToListeners(WebInspector.UISourceCode.Events.LineDecorat
ionRemoved, marker); |
| 487 | 646 }); |
| 488 /** | 647 } |
| 489 * @param {string} newWorkingCopy | 648 |
| 490 */ | 649 /** |
| 491 setWorkingCopy: function(newWorkingCopy) | 650 * @param {string} type |
| 492 { | 651 * @return {?Map<number, !WebInspector.UISourceCode.LineMarker>} |
| 493 this._workingCopy = newWorkingCopy; | 652 */ |
| 494 delete this._workingCopyGetter; | 653 lineDecorations(type) { |
| 495 this.dispatchEventToListeners(WebInspector.UISourceCode.Events.WorkingCo
pyChanged); | 654 return this._lineDecorations.get(type) || null; |
| 496 this._project.workspace().dispatchEventToListeners(WebInspector.Workspac
e.Events.WorkingCopyChanged, { uiSourceCode: this }); | 655 } |
| 497 }, | |
| 498 | |
| 499 setWorkingCopyGetter: function(workingCopyGetter) | |
| 500 { | |
| 501 this._workingCopyGetter = workingCopyGetter; | |
| 502 this.dispatchEventToListeners(WebInspector.UISourceCode.Events.WorkingCo
pyChanged); | |
| 503 this._project.workspace().dispatchEventToListeners(WebInspector.Workspac
e.Events.WorkingCopyChanged, { uiSourceCode: this }); | |
| 504 }, | |
| 505 | |
| 506 removeWorkingCopyGetter: function() | |
| 507 { | |
| 508 if (!this._workingCopyGetter) | |
| 509 return; | |
| 510 this._workingCopy = this._workingCopyGetter(); | |
| 511 delete this._workingCopyGetter; | |
| 512 }, | |
| 513 | |
| 514 commitWorkingCopy: function() | |
| 515 { | |
| 516 if (this.isDirty()) | |
| 517 this._commitContent(this.workingCopy()); | |
| 518 }, | |
| 519 | |
| 520 /** | |
| 521 * @return {boolean} | |
| 522 */ | |
| 523 isDirty: function() | |
| 524 { | |
| 525 return typeof this._workingCopy !== "undefined" || typeof this._workingC
opyGetter !== "undefined"; | |
| 526 }, | |
| 527 | |
| 528 /** | |
| 529 * @return {string} | |
| 530 */ | |
| 531 extension: function() | |
| 532 { | |
| 533 return WebInspector.ParsedURL.extractExtension(this._name); | |
| 534 }, | |
| 535 | |
| 536 /** | |
| 537 * @return {?string} | |
| 538 */ | |
| 539 content: function() | |
| 540 { | |
| 541 return this._content; | |
| 542 }, | |
| 543 | |
| 544 /** | |
| 545 * @override | |
| 546 * @param {string} query | |
| 547 * @param {boolean} caseSensitive | |
| 548 * @param {boolean} isRegex | |
| 549 * @param {function(!Array.<!WebInspector.ContentProvider.SearchMatch>)} cal
lback | |
| 550 */ | |
| 551 searchInContent: function(query, caseSensitive, isRegex, callback) | |
| 552 { | |
| 553 var content = this.content(); | |
| 554 if (!content) { | |
| 555 this._project.searchInFileContent(this, query, caseSensitive, isRege
x, callback); | |
| 556 return; | |
| 557 } | |
| 558 | |
| 559 // searchInContent should call back later. | |
| 560 setTimeout(doSearch.bind(null, content), 0); | |
| 561 | |
| 562 /** | |
| 563 * @param {string} content | |
| 564 */ | |
| 565 function doSearch(content) | |
| 566 { | |
| 567 callback(WebInspector.ContentProvider.performSearchInContent(content
, query, caseSensitive, isRegex)); | |
| 568 } | |
| 569 }, | |
| 570 | |
| 571 /** | |
| 572 * @param {?string} content | |
| 573 */ | |
| 574 _fireContentAvailable: function(content) | |
| 575 { | |
| 576 this._contentLoaded = true; | |
| 577 this._content = content; | |
| 578 | |
| 579 var callback = this._requestContentCallback; | |
| 580 this._requestContentCallback = null; | |
| 581 this._requestContentPromise = null; | |
| 582 | |
| 583 callback.call(null, content); | |
| 584 }, | |
| 585 | |
| 586 /** | |
| 587 * @return {boolean} | |
| 588 */ | |
| 589 contentLoaded: function() | |
| 590 { | |
| 591 return this._contentLoaded; | |
| 592 }, | |
| 593 | |
| 594 /** | |
| 595 * @param {number} lineNumber | |
| 596 * @param {number=} columnNumber | |
| 597 * @return {!WebInspector.UILocation} | |
| 598 */ | |
| 599 uiLocation: function(lineNumber, columnNumber) | |
| 600 { | |
| 601 if (typeof columnNumber === "undefined") | |
| 602 columnNumber = 0; | |
| 603 return new WebInspector.UILocation(this, lineNumber, columnNumber); | |
| 604 }, | |
| 605 | |
| 606 /** | |
| 607 * @return {!Array<!WebInspector.UISourceCode.Message>} | |
| 608 */ | |
| 609 messages: function() | |
| 610 { | |
| 611 return this._messages.slice(); | |
| 612 }, | |
| 613 | |
| 614 /** | |
| 615 * @param {!WebInspector.UISourceCode.Message.Level} level | |
| 616 * @param {string} text | |
| 617 * @param {number} lineNumber | |
| 618 * @param {number=} columnNumber | |
| 619 * @return {!WebInspector.UISourceCode.Message} message | |
| 620 */ | |
| 621 addLineMessage: function(level, text, lineNumber, columnNumber) | |
| 622 { | |
| 623 return this.addMessage(level, text, new WebInspector.TextRange(lineNumbe
r, columnNumber || 0, lineNumber, columnNumber || 0)); | |
| 624 }, | |
| 625 | |
| 626 /** | |
| 627 * @param {!WebInspector.UISourceCode.Message.Level} level | |
| 628 * @param {string} text | |
| 629 * @param {!WebInspector.TextRange} range | |
| 630 * @return {!WebInspector.UISourceCode.Message} message | |
| 631 */ | |
| 632 addMessage: function(level, text, range) | |
| 633 { | |
| 634 var message = new WebInspector.UISourceCode.Message(this, level, text, r
ange); | |
| 635 this._messages.push(message); | |
| 636 this.dispatchEventToListeners(WebInspector.UISourceCode.Events.MessageAd
ded, message); | |
| 637 return message; | |
| 638 }, | |
| 639 | |
| 640 /** | |
| 641 * @param {!WebInspector.UISourceCode.Message} message | |
| 642 */ | |
| 643 removeMessage: function(message) | |
| 644 { | |
| 645 if (this._messages.remove(message)) | |
| 646 this.dispatchEventToListeners(WebInspector.UISourceCode.Events.Messa
geRemoved, message); | |
| 647 }, | |
| 648 | |
| 649 removeAllMessages: function() | |
| 650 { | |
| 651 var messages = this._messages; | |
| 652 this._messages = []; | |
| 653 for (var message of messages) | |
| 654 this.dispatchEventToListeners(WebInspector.UISourceCode.Events.Messa
geRemoved, message); | |
| 655 }, | |
| 656 | |
| 657 /** | |
| 658 * @param {number} lineNumber | |
| 659 * @param {string} type | |
| 660 * @param {?} data | |
| 661 */ | |
| 662 addLineDecoration: function(lineNumber, type, data) | |
| 663 { | |
| 664 var markers = this._lineDecorations.get(type); | |
| 665 if (!markers) { | |
| 666 markers = new Map(); | |
| 667 this._lineDecorations.set(type, markers); | |
| 668 } | |
| 669 var marker = new WebInspector.UISourceCode.LineMarker(lineNumber, type,
data); | |
| 670 markers.set(lineNumber, marker); | |
| 671 this.dispatchEventToListeners(WebInspector.UISourceCode.Events.LineDecor
ationAdded, marker); | |
| 672 }, | |
| 673 | |
| 674 /** | |
| 675 * @param {number} lineNumber | |
| 676 * @param {string} type | |
| 677 */ | |
| 678 removeLineDecoration: function(lineNumber, type) | |
| 679 { | |
| 680 var markers = this._lineDecorations.get(type); | |
| 681 if (!markers) | |
| 682 return; | |
| 683 var marker = markers.get(lineNumber); | |
| 684 if (!marker) | |
| 685 return; | |
| 686 markers.delete(lineNumber); | |
| 687 this.dispatchEventToListeners(WebInspector.UISourceCode.Events.LineDecor
ationRemoved, marker); | |
| 688 if (!markers.size) | |
| 689 this._lineDecorations.delete(type); | |
| 690 }, | |
| 691 | |
| 692 /** | |
| 693 * @param {string} type | |
| 694 */ | |
| 695 removeAllLineDecorations: function(type) | |
| 696 { | |
| 697 var markers = this._lineDecorations.get(type); | |
| 698 if (!markers) | |
| 699 return; | |
| 700 this._lineDecorations.delete(type); | |
| 701 markers.forEach(marker => { | |
| 702 this.dispatchEventToListeners(WebInspector.UISourceCode.Events.LineD
ecorationRemoved, marker); | |
| 703 }); | |
| 704 }, | |
| 705 | |
| 706 /** | |
| 707 * @param {string} type | |
| 708 * @return {?Map<number, !WebInspector.UISourceCode.LineMarker>} | |
| 709 */ | |
| 710 lineDecorations: function(type) | |
| 711 { | |
| 712 return this._lineDecorations.get(type) || null; | |
| 713 }, | |
| 714 | |
| 715 __proto__: WebInspector.Object.prototype | |
| 716 }; | 656 }; |
| 717 | 657 |
| 658 /** @enum {symbol} */ |
| 659 WebInspector.UISourceCode.Events = { |
| 660 WorkingCopyChanged: Symbol('WorkingCopyChanged'), |
| 661 WorkingCopyCommitted: Symbol('WorkingCopyCommitted'), |
| 662 TitleChanged: Symbol('TitleChanged'), |
| 663 SourceMappingChanged: Symbol('SourceMappingChanged'), |
| 664 MessageAdded: Symbol('MessageAdded'), |
| 665 MessageRemoved: Symbol('MessageRemoved'), |
| 666 LineDecorationAdded: Symbol('LineDecorationAdded'), |
| 667 LineDecorationRemoved: Symbol('LineDecorationRemoved') |
| 668 }; |
| 669 |
| 718 /** | 670 /** |
| 719 * @constructor | 671 * @unrestricted |
| 720 * @param {!WebInspector.UISourceCode} uiSourceCode | |
| 721 * @param {number} lineNumber | |
| 722 * @param {number} columnNumber | |
| 723 */ | 672 */ |
| 724 WebInspector.UILocation = function(uiSourceCode, lineNumber, columnNumber) | 673 WebInspector.UILocation = class { |
| 725 { | 674 /** |
| 675 * @param {!WebInspector.UISourceCode} uiSourceCode |
| 676 * @param {number} lineNumber |
| 677 * @param {number} columnNumber |
| 678 */ |
| 679 constructor(uiSourceCode, lineNumber, columnNumber) { |
| 726 this.uiSourceCode = uiSourceCode; | 680 this.uiSourceCode = uiSourceCode; |
| 727 this.lineNumber = lineNumber; | 681 this.lineNumber = lineNumber; |
| 728 this.columnNumber = columnNumber; | 682 this.columnNumber = columnNumber; |
| 683 } |
| 684 |
| 685 /** |
| 686 * @return {string} |
| 687 */ |
| 688 linkText() { |
| 689 var linkText = this.uiSourceCode.displayName(); |
| 690 if (typeof this.lineNumber === 'number') |
| 691 linkText += ':' + (this.lineNumber + 1); |
| 692 return linkText; |
| 693 } |
| 694 |
| 695 /** |
| 696 * @return {string} |
| 697 */ |
| 698 id() { |
| 699 return this.uiSourceCode.project().id() + ':' + this.uiSourceCode.url() + ':
' + this.lineNumber + ':' + |
| 700 this.columnNumber; |
| 701 } |
| 702 |
| 703 /** |
| 704 * @return {string} |
| 705 */ |
| 706 toUIString() { |
| 707 return this.uiSourceCode.url() + ':' + (this.lineNumber + 1); |
| 708 } |
| 729 }; | 709 }; |
| 730 | 710 |
| 731 WebInspector.UILocation.prototype = { | |
| 732 /** | |
| 733 * @return {string} | |
| 734 */ | |
| 735 linkText: function() | |
| 736 { | |
| 737 var linkText = this.uiSourceCode.displayName(); | |
| 738 if (typeof this.lineNumber === "number") | |
| 739 linkText += ":" + (this.lineNumber + 1); | |
| 740 return linkText; | |
| 741 }, | |
| 742 | |
| 743 /** | |
| 744 * @return {string} | |
| 745 */ | |
| 746 id: function() | |
| 747 { | |
| 748 return this.uiSourceCode.project().id() + ":" + this.uiSourceCode.url()
+ ":" + this.lineNumber + ":" + this.columnNumber; | |
| 749 }, | |
| 750 | |
| 751 /** | |
| 752 * @return {string} | |
| 753 */ | |
| 754 toUIString: function() | |
| 755 { | |
| 756 return this.uiSourceCode.url() + ":" + (this.lineNumber + 1); | |
| 757 } | |
| 758 }; | |
| 759 | |
| 760 /** | 711 /** |
| 761 * @constructor | |
| 762 * @implements {WebInspector.ContentProvider} | 712 * @implements {WebInspector.ContentProvider} |
| 763 * @param {!WebInspector.UISourceCode} uiSourceCode | 713 * @unrestricted |
| 764 * @param {?string|undefined} content | |
| 765 * @param {!Date} timestamp | |
| 766 */ | 714 */ |
| 767 WebInspector.Revision = function(uiSourceCode, content, timestamp) | 715 WebInspector.Revision = class { |
| 768 { | 716 /** |
| 717 * @param {!WebInspector.UISourceCode} uiSourceCode |
| 718 * @param {?string|undefined} content |
| 719 * @param {!Date} timestamp |
| 720 */ |
| 721 constructor(uiSourceCode, content, timestamp) { |
| 769 this._uiSourceCode = uiSourceCode; | 722 this._uiSourceCode = uiSourceCode; |
| 770 this._content = content; | 723 this._content = content; |
| 771 this._timestamp = timestamp; | 724 this._timestamp = timestamp; |
| 725 } |
| 726 |
| 727 /** |
| 728 * @return {!WebInspector.UISourceCode} |
| 729 */ |
| 730 get uiSourceCode() { |
| 731 return this._uiSourceCode; |
| 732 } |
| 733 |
| 734 /** |
| 735 * @return {!Date} |
| 736 */ |
| 737 get timestamp() { |
| 738 return this._timestamp; |
| 739 } |
| 740 |
| 741 /** |
| 742 * @return {?string} |
| 743 */ |
| 744 get content() { |
| 745 return this._content || null; |
| 746 } |
| 747 |
| 748 /** |
| 749 * @return {!Promise} |
| 750 */ |
| 751 revertToThis() { |
| 752 /** |
| 753 * @param {?string} content |
| 754 * @this {WebInspector.Revision} |
| 755 */ |
| 756 function revert(content) { |
| 757 if (content && this._uiSourceCode._content !== content) |
| 758 this._uiSourceCode.addRevision(content); |
| 759 } |
| 760 WebInspector.userMetrics.actionTaken(WebInspector.UserMetrics.Action.Revisio
nApplied); |
| 761 return this.requestContent().then(revert.bind(this)); |
| 762 } |
| 763 |
| 764 /** |
| 765 * @override |
| 766 * @return {string} |
| 767 */ |
| 768 contentURL() { |
| 769 return this._uiSourceCode.url(); |
| 770 } |
| 771 |
| 772 /** |
| 773 * @override |
| 774 * @return {!WebInspector.ResourceType} |
| 775 */ |
| 776 contentType() { |
| 777 return this._uiSourceCode.contentType(); |
| 778 } |
| 779 |
| 780 /** |
| 781 * @override |
| 782 * @return {!Promise<?string>} |
| 783 */ |
| 784 requestContent() { |
| 785 return Promise.resolve(/** @type {?string} */ (this._content || '')); |
| 786 } |
| 787 |
| 788 /** |
| 789 * @override |
| 790 * @param {string} query |
| 791 * @param {boolean} caseSensitive |
| 792 * @param {boolean} isRegex |
| 793 * @param {function(!Array.<!WebInspector.ContentProvider.SearchMatch>)} callb
ack |
| 794 */ |
| 795 searchInContent(query, caseSensitive, isRegex, callback) { |
| 796 callback([]); |
| 797 } |
| 772 }; | 798 }; |
| 773 | 799 |
| 774 WebInspector.Revision.prototype = { | |
| 775 /** | |
| 776 * @return {!WebInspector.UISourceCode} | |
| 777 */ | |
| 778 get uiSourceCode() | |
| 779 { | |
| 780 return this._uiSourceCode; | |
| 781 }, | |
| 782 | |
| 783 /** | |
| 784 * @return {!Date} | |
| 785 */ | |
| 786 get timestamp() | |
| 787 { | |
| 788 return this._timestamp; | |
| 789 }, | |
| 790 | |
| 791 /** | |
| 792 * @return {?string} | |
| 793 */ | |
| 794 get content() | |
| 795 { | |
| 796 return this._content || null; | |
| 797 }, | |
| 798 | |
| 799 /** | |
| 800 * @return {!Promise} | |
| 801 */ | |
| 802 revertToThis: function() | |
| 803 { | |
| 804 /** | |
| 805 * @param {?string} content | |
| 806 * @this {WebInspector.Revision} | |
| 807 */ | |
| 808 function revert(content) | |
| 809 { | |
| 810 if (content && this._uiSourceCode._content !== content) | |
| 811 this._uiSourceCode.addRevision(content); | |
| 812 } | |
| 813 WebInspector.userMetrics.actionTaken(WebInspector.UserMetrics.Action.Rev
isionApplied); | |
| 814 return this.requestContent().then(revert.bind(this)); | |
| 815 }, | |
| 816 | |
| 817 /** | |
| 818 * @override | |
| 819 * @return {string} | |
| 820 */ | |
| 821 contentURL: function() | |
| 822 { | |
| 823 return this._uiSourceCode.url(); | |
| 824 }, | |
| 825 | |
| 826 /** | |
| 827 * @override | |
| 828 * @return {!WebInspector.ResourceType} | |
| 829 */ | |
| 830 contentType: function() | |
| 831 { | |
| 832 return this._uiSourceCode.contentType(); | |
| 833 }, | |
| 834 | |
| 835 /** | |
| 836 * @override | |
| 837 * @return {!Promise<?string>} | |
| 838 */ | |
| 839 requestContent: function() | |
| 840 { | |
| 841 return Promise.resolve(/** @type {?string} */(this._content || "")); | |
| 842 }, | |
| 843 | |
| 844 /** | |
| 845 * @override | |
| 846 * @param {string} query | |
| 847 * @param {boolean} caseSensitive | |
| 848 * @param {boolean} isRegex | |
| 849 * @param {function(!Array.<!WebInspector.ContentProvider.SearchMatch>)} cal
lback | |
| 850 */ | |
| 851 searchInContent: function(query, caseSensitive, isRegex, callback) | |
| 852 { | |
| 853 callback([]); | |
| 854 } | |
| 855 }; | |
| 856 | |
| 857 /** | 800 /** |
| 858 * @constructor | 801 * @unrestricted |
| 859 * @param {!WebInspector.UISourceCode} uiSourceCode | |
| 860 * @param {!WebInspector.UISourceCode.Message.Level} level | |
| 861 * @param {string} text | |
| 862 * @param {!WebInspector.TextRange} range | |
| 863 */ | 802 */ |
| 864 WebInspector.UISourceCode.Message = function(uiSourceCode, level, text, range) | 803 WebInspector.UISourceCode.Message = class { |
| 865 { | 804 /** |
| 805 * @param {!WebInspector.UISourceCode} uiSourceCode |
| 806 * @param {!WebInspector.UISourceCode.Message.Level} level |
| 807 * @param {string} text |
| 808 * @param {!WebInspector.TextRange} range |
| 809 */ |
| 810 constructor(uiSourceCode, level, text, range) { |
| 866 this._uiSourceCode = uiSourceCode; | 811 this._uiSourceCode = uiSourceCode; |
| 867 this._level = level; | 812 this._level = level; |
| 868 this._text = text; | 813 this._text = text; |
| 869 this._range = range; | 814 this._range = range; |
| 815 } |
| 816 |
| 817 /** |
| 818 * @return {!WebInspector.UISourceCode} |
| 819 */ |
| 820 uiSourceCode() { |
| 821 return this._uiSourceCode; |
| 822 } |
| 823 |
| 824 /** |
| 825 * @return {!WebInspector.UISourceCode.Message.Level} |
| 826 */ |
| 827 level() { |
| 828 return this._level; |
| 829 } |
| 830 |
| 831 /** |
| 832 * @return {string} |
| 833 */ |
| 834 text() { |
| 835 return this._text; |
| 836 } |
| 837 |
| 838 /** |
| 839 * @return {!WebInspector.TextRange} |
| 840 */ |
| 841 range() { |
| 842 return this._range; |
| 843 } |
| 844 |
| 845 /** |
| 846 * @return {number} |
| 847 */ |
| 848 lineNumber() { |
| 849 return this._range.startLine; |
| 850 } |
| 851 |
| 852 /** |
| 853 * @return {(number|undefined)} |
| 854 */ |
| 855 columnNumber() { |
| 856 return this._range.startColumn; |
| 857 } |
| 858 |
| 859 /** |
| 860 * @param {!WebInspector.UISourceCode.Message} another |
| 861 * @return {boolean} |
| 862 */ |
| 863 isEqual(another) { |
| 864 return this._uiSourceCode === another._uiSourceCode && this.text() === anoth
er.text() && |
| 865 this.level() === another.level() && this.range().equal(another.range()); |
| 866 } |
| 867 |
| 868 remove() { |
| 869 this._uiSourceCode.removeMessage(this); |
| 870 } |
| 870 }; | 871 }; |
| 871 | 872 |
| 872 /** | 873 /** |
| 873 * @enum {string} | 874 * @enum {string} |
| 874 */ | 875 */ |
| 875 WebInspector.UISourceCode.Message.Level = { | 876 WebInspector.UISourceCode.Message.Level = { |
| 876 Error: "Error", | 877 Error: 'Error', |
| 877 Warning: "Warning" | 878 Warning: 'Warning' |
| 878 }; | 879 }; |
| 879 | 880 |
| 880 WebInspector.UISourceCode.Message.prototype = { | |
| 881 /** | |
| 882 * @return {!WebInspector.UISourceCode} | |
| 883 */ | |
| 884 uiSourceCode: function() | |
| 885 { | |
| 886 return this._uiSourceCode; | |
| 887 }, | |
| 888 | |
| 889 /** | |
| 890 * @return {!WebInspector.UISourceCode.Message.Level} | |
| 891 */ | |
| 892 level: function() | |
| 893 { | |
| 894 return this._level; | |
| 895 }, | |
| 896 | |
| 897 /** | |
| 898 * @return {string} | |
| 899 */ | |
| 900 text: function() | |
| 901 { | |
| 902 return this._text; | |
| 903 }, | |
| 904 | |
| 905 /** | |
| 906 * @return {!WebInspector.TextRange} | |
| 907 */ | |
| 908 range: function() | |
| 909 { | |
| 910 return this._range; | |
| 911 }, | |
| 912 | |
| 913 /** | |
| 914 * @return {number} | |
| 915 */ | |
| 916 lineNumber: function() | |
| 917 { | |
| 918 return this._range.startLine; | |
| 919 }, | |
| 920 | |
| 921 /** | |
| 922 * @return {(number|undefined)} | |
| 923 */ | |
| 924 columnNumber: function() | |
| 925 { | |
| 926 return this._range.startColumn; | |
| 927 }, | |
| 928 | |
| 929 /** | |
| 930 * @param {!WebInspector.UISourceCode.Message} another | |
| 931 * @return {boolean} | |
| 932 */ | |
| 933 isEqual: function(another) | |
| 934 { | |
| 935 return this._uiSourceCode === another._uiSourceCode && this.text() === a
nother.text() && this.level() === another.level() && this.range().equal(another.
range()); | |
| 936 }, | |
| 937 | |
| 938 remove: function() | |
| 939 { | |
| 940 this._uiSourceCode.removeMessage(this); | |
| 941 } | |
| 942 }; | |
| 943 | |
| 944 /** | 881 /** |
| 945 * @constructor | 882 * @unrestricted |
| 946 * @param {number} line | |
| 947 * @param {string} type | |
| 948 * @param {?} data | |
| 949 */ | 883 */ |
| 950 WebInspector.UISourceCode.LineMarker = function(line, type, data) | 884 WebInspector.UISourceCode.LineMarker = class { |
| 951 { | 885 /** |
| 886 * @param {number} line |
| 887 * @param {string} type |
| 888 * @param {?} data |
| 889 */ |
| 890 constructor(line, type, data) { |
| 952 this._line = line; | 891 this._line = line; |
| 953 this._type = type; | 892 this._type = type; |
| 954 this._data = data; | 893 this._data = data; |
| 894 } |
| 895 |
| 896 /** |
| 897 * @return {number} |
| 898 */ |
| 899 line() { |
| 900 return this._line; |
| 901 } |
| 902 |
| 903 /** |
| 904 * @return {string} |
| 905 */ |
| 906 type() { |
| 907 return this._type; |
| 908 } |
| 909 |
| 910 /** |
| 911 * @return {*} |
| 912 */ |
| 913 data() { |
| 914 return this._data; |
| 915 } |
| 955 }; | 916 }; |
| 956 | 917 |
| 957 WebInspector.UISourceCode.LineMarker.prototype = { | |
| 958 /** | |
| 959 * @return {number} | |
| 960 */ | |
| 961 line: function() | |
| 962 { | |
| 963 return this._line; | |
| 964 }, | |
| 965 | |
| 966 /** | |
| 967 * @return {string} | |
| 968 */ | |
| 969 type: function() | |
| 970 { | |
| 971 return this._type; | |
| 972 }, | |
| 973 | |
| 974 /** | |
| 975 * @return {*} | |
| 976 */ | |
| 977 data: function() | |
| 978 { | |
| 979 return this._data; | |
| 980 } | |
| 981 }; | |
| 982 | |
| 983 /** | 918 /** |
| 984 * @constructor | 919 * @unrestricted |
| 985 * @param {?Date} modificationTime | |
| 986 * @param {?number} contentSize | |
| 987 */ | 920 */ |
| 988 WebInspector.UISourceCodeMetadata = function(modificationTime, contentSize) | 921 WebInspector.UISourceCodeMetadata = class { |
| 989 { | 922 /** |
| 923 * @param {?Date} modificationTime |
| 924 * @param {?number} contentSize |
| 925 */ |
| 926 constructor(modificationTime, contentSize) { |
| 990 this.modificationTime = modificationTime; | 927 this.modificationTime = modificationTime; |
| 991 this.contentSize = contentSize; | 928 this.contentSize = contentSize; |
| 929 } |
| 992 }; | 930 }; |
| OLD | NEW |