| OLD | NEW |
| (Empty) |
| 1 /* | |
| 2 * Copyright (C) 2013 Google Inc. All rights reserved. | |
| 3 * | |
| 4 * Redistribution and use in source and binary forms, with or without | |
| 5 * modification, are permitted provided that the following conditions are | |
| 6 * met: | |
| 7 * | |
| 8 * * Redistributions of source code must retain the above copyright | |
| 9 * notice, this list of conditions and the following disclaimer. | |
| 10 * * Redistributions in binary form must reproduce the above | |
| 11 * copyright notice, this list of conditions and the following disclaimer | |
| 12 * in the documentation and/or other materials provided with the | |
| 13 * distribution. | |
| 14 * * Neither the name of Google Inc. nor the names of its | |
| 15 * contributors may be used to endorse or promote products derived from | |
| 16 * this software without specific prior written permission. | |
| 17 * | |
| 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |
| 19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |
| 20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |
| 21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | |
| 22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |
| 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |
| 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
| 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
| 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
| 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. | |
| 29 */ | |
| 30 | |
| 31 /** | |
| 32 * @unrestricted | |
| 33 */ | |
| 34 Workspace.IsolatedFileSystem = class { | |
| 35 /** | |
| 36 * @param {!Workspace.IsolatedFileSystemManager} manager | |
| 37 * @param {string} path | |
| 38 * @param {string} embedderPath | |
| 39 * @param {!DOMFileSystem} domFileSystem | |
| 40 */ | |
| 41 constructor(manager, path, embedderPath, domFileSystem) { | |
| 42 this._manager = manager; | |
| 43 this._path = path; | |
| 44 this._embedderPath = embedderPath; | |
| 45 this._domFileSystem = domFileSystem; | |
| 46 this._excludedFoldersSetting = Common.settings.createLocalSetting('workspace
ExcludedFolders', {}); | |
| 47 /** @type {!Set<string>} */ | |
| 48 this._excludedFolders = new Set(this._excludedFoldersSetting.get()[path] ||
[]); | |
| 49 | |
| 50 /** @type {!Set<string>} */ | |
| 51 this._initialFilePaths = new Set(); | |
| 52 /** @type {!Set<string>} */ | |
| 53 this._initialGitFolders = new Set(); | |
| 54 } | |
| 55 | |
| 56 /** | |
| 57 * @param {!Workspace.IsolatedFileSystemManager} manager | |
| 58 * @param {string} path | |
| 59 * @param {string} embedderPath | |
| 60 * @param {string} name | |
| 61 * @param {string} rootURL | |
| 62 * @return {!Promise<?Workspace.IsolatedFileSystem>} | |
| 63 */ | |
| 64 static create(manager, path, embedderPath, name, rootURL) { | |
| 65 var domFileSystem = InspectorFrontendHost.isolatedFileSystem(name, rootURL); | |
| 66 if (!domFileSystem) | |
| 67 return Promise.resolve(/** @type {?Workspace.IsolatedFileSystem} */ (null)
); | |
| 68 | |
| 69 var fileSystem = new Workspace.IsolatedFileSystem(manager, path, embedderPat
h, domFileSystem); | |
| 70 return fileSystem._initializeFilePaths() | |
| 71 .then(() => fileSystem) | |
| 72 .catchException(/** @type {?Workspace.IsolatedFileSystem} */ (null)); | |
| 73 } | |
| 74 | |
| 75 /** | |
| 76 * @param {!DOMError} error | |
| 77 * @return {string} | |
| 78 */ | |
| 79 static errorMessage(error) { | |
| 80 return Common.UIString('File system error: %s', error.message); | |
| 81 } | |
| 82 | |
| 83 /** | |
| 84 * @param {string} path | |
| 85 * @return {!Promise<?{modificationTime: !Date, size: number}>} | |
| 86 */ | |
| 87 getMetadata(path) { | |
| 88 var fulfill; | |
| 89 var promise = new Promise(f => fulfill = f); | |
| 90 this._domFileSystem.root.getFile(path, undefined, fileEntryLoaded, errorHand
ler); | |
| 91 return promise; | |
| 92 | |
| 93 /** | |
| 94 * @param {!FileEntry} entry | |
| 95 */ | |
| 96 function fileEntryLoaded(entry) { | |
| 97 entry.getMetadata(fulfill, errorHandler); | |
| 98 } | |
| 99 | |
| 100 /** | |
| 101 * @param {!FileError} error | |
| 102 */ | |
| 103 function errorHandler(error) { | |
| 104 var errorMessage = Workspace.IsolatedFileSystem.errorMessage(error); | |
| 105 console.error(errorMessage + ' when getting file metadata \'' + path); | |
| 106 fulfill(null); | |
| 107 } | |
| 108 } | |
| 109 | |
| 110 /** | |
| 111 * @return {!Array<string>} | |
| 112 */ | |
| 113 initialFilePaths() { | |
| 114 return this._initialFilePaths.valuesArray(); | |
| 115 } | |
| 116 | |
| 117 /** | |
| 118 * @return {!Array<string>} | |
| 119 */ | |
| 120 initialGitFolders() { | |
| 121 return this._initialGitFolders.valuesArray(); | |
| 122 } | |
| 123 | |
| 124 /** | |
| 125 * @return {string} | |
| 126 */ | |
| 127 path() { | |
| 128 return this._path; | |
| 129 } | |
| 130 | |
| 131 /** | |
| 132 * @return {string} | |
| 133 */ | |
| 134 embedderPath() { | |
| 135 return this._embedderPath; | |
| 136 } | |
| 137 | |
| 138 /** | |
| 139 * @return {!Promise} | |
| 140 */ | |
| 141 _initializeFilePaths() { | |
| 142 var fulfill; | |
| 143 var promise = new Promise(x => fulfill = x); | |
| 144 var pendingRequests = 1; | |
| 145 var boundInnerCallback = innerCallback.bind(this); | |
| 146 this._requestEntries('', boundInnerCallback); | |
| 147 return promise; | |
| 148 | |
| 149 /** | |
| 150 * @param {!Array.<!FileEntry>} entries | |
| 151 * @this {Workspace.IsolatedFileSystem} | |
| 152 */ | |
| 153 function innerCallback(entries) { | |
| 154 for (var i = 0; i < entries.length; ++i) { | |
| 155 var entry = entries[i]; | |
| 156 if (!entry.isDirectory) { | |
| 157 if (this._isFileExcluded(entry.fullPath)) | |
| 158 continue; | |
| 159 this._initialFilePaths.add(entry.fullPath.substr(1)); | |
| 160 } else { | |
| 161 if (entry.fullPath.endsWith('/.git')) { | |
| 162 var lastSlash = entry.fullPath.lastIndexOf('/'); | |
| 163 var parentFolder = entry.fullPath.substring(1, lastSlash); | |
| 164 this._initialGitFolders.add(parentFolder); | |
| 165 } | |
| 166 if (this._isFileExcluded(entry.fullPath + '/')) | |
| 167 continue; | |
| 168 ++pendingRequests; | |
| 169 this._requestEntries(entry.fullPath, boundInnerCallback); | |
| 170 } | |
| 171 } | |
| 172 if ((--pendingRequests === 0)) | |
| 173 fulfill(); | |
| 174 } | |
| 175 } | |
| 176 | |
| 177 /** | |
| 178 * @param {string} path | |
| 179 * @param {?string} name | |
| 180 * @param {function(?string)} callback | |
| 181 */ | |
| 182 createFile(path, name, callback) { | |
| 183 var newFileIndex = 1; | |
| 184 if (!name) | |
| 185 name = 'NewFile'; | |
| 186 var nameCandidate; | |
| 187 | |
| 188 this._domFileSystem.root.getDirectory(path, undefined, dirEntryLoaded.bind(t
his), errorHandler.bind(this)); | |
| 189 | |
| 190 /** | |
| 191 * @param {!DirectoryEntry} dirEntry | |
| 192 * @this {Workspace.IsolatedFileSystem} | |
| 193 */ | |
| 194 function dirEntryLoaded(dirEntry) { | |
| 195 var nameCandidate = name; | |
| 196 if (newFileIndex > 1) | |
| 197 nameCandidate += newFileIndex; | |
| 198 ++newFileIndex; | |
| 199 dirEntry.getFile(nameCandidate, {create: true, exclusive: true}, fileCreat
ed, fileCreationError.bind(this)); | |
| 200 | |
| 201 function fileCreated(entry) { | |
| 202 callback(entry.fullPath.substr(1)); | |
| 203 } | |
| 204 | |
| 205 /** | |
| 206 * @this {Workspace.IsolatedFileSystem} | |
| 207 */ | |
| 208 function fileCreationError(error) { | |
| 209 if (error.name === 'InvalidModificationError') { | |
| 210 dirEntryLoaded.call(this, dirEntry); | |
| 211 return; | |
| 212 } | |
| 213 var errorMessage = Workspace.IsolatedFileSystem.errorMessage(error); | |
| 214 console.error( | |
| 215 errorMessage + ' when testing if file exists \'' + (this._path + '/'
+ path + '/' + nameCandidate) + '\''); | |
| 216 callback(null); | |
| 217 } | |
| 218 } | |
| 219 | |
| 220 /** | |
| 221 * @this {Workspace.IsolatedFileSystem} | |
| 222 */ | |
| 223 function errorHandler(error) { | |
| 224 var errorMessage = Workspace.IsolatedFileSystem.errorMessage(error); | |
| 225 var filePath = this._path + '/' + path; | |
| 226 if (nameCandidate) | |
| 227 filePath += '/' + nameCandidate; | |
| 228 console.error(errorMessage + ' when getting content for file \'' + (filePa
th) + '\''); | |
| 229 callback(null); | |
| 230 } | |
| 231 } | |
| 232 | |
| 233 /** | |
| 234 * @param {string} path | |
| 235 */ | |
| 236 deleteFile(path) { | |
| 237 this._domFileSystem.root.getFile(path, undefined, fileEntryLoaded.bind(this)
, errorHandler.bind(this)); | |
| 238 | |
| 239 /** | |
| 240 * @param {!FileEntry} fileEntry | |
| 241 * @this {Workspace.IsolatedFileSystem} | |
| 242 */ | |
| 243 function fileEntryLoaded(fileEntry) { | |
| 244 fileEntry.remove(fileEntryRemoved, errorHandler.bind(this)); | |
| 245 } | |
| 246 | |
| 247 function fileEntryRemoved() { | |
| 248 } | |
| 249 | |
| 250 /** | |
| 251 * @param {!FileError} error | |
| 252 * @this {Workspace.IsolatedFileSystem} | |
| 253 * @suppress {checkTypes} | |
| 254 * TODO(jsbell): Update externs replacing FileError with DOMException. https
://crbug.com/496901 | |
| 255 */ | |
| 256 function errorHandler(error) { | |
| 257 var errorMessage = Workspace.IsolatedFileSystem.errorMessage(error); | |
| 258 console.error(errorMessage + ' when deleting file \'' + (this._path + '/'
+ path) + '\''); | |
| 259 } | |
| 260 } | |
| 261 | |
| 262 /** | |
| 263 * @param {string} path | |
| 264 * @return {!Promise<?string>} | |
| 265 */ | |
| 266 requestFileContentPromise(path) { | |
| 267 var fulfill; | |
| 268 var promise = new Promise(x => fulfill = x); | |
| 269 this.requestFileContent(path, fulfill); | |
| 270 return promise; | |
| 271 } | |
| 272 | |
| 273 /** | |
| 274 * @param {string} path | |
| 275 * @param {function(?string)} callback | |
| 276 */ | |
| 277 requestFileContent(path, callback) { | |
| 278 this._domFileSystem.root.getFile(path, undefined, fileEntryLoaded.bind(this)
, errorHandler.bind(this)); | |
| 279 | |
| 280 /** | |
| 281 * @param {!FileEntry} entry | |
| 282 * @this {Workspace.IsolatedFileSystem} | |
| 283 */ | |
| 284 function fileEntryLoaded(entry) { | |
| 285 entry.file(fileLoaded, errorHandler.bind(this)); | |
| 286 } | |
| 287 | |
| 288 /** | |
| 289 * @param {!Blob} file | |
| 290 */ | |
| 291 function fileLoaded(file) { | |
| 292 var reader = new FileReader(); | |
| 293 reader.onloadend = readerLoadEnd; | |
| 294 if (Workspace.IsolatedFileSystem.ImageExtensions.has(Common.ParsedURL.extr
actExtension(path))) | |
| 295 reader.readAsDataURL(file); | |
| 296 else | |
| 297 reader.readAsText(file); | |
| 298 } | |
| 299 | |
| 300 /** | |
| 301 * @this {!FileReader} | |
| 302 */ | |
| 303 function readerLoadEnd() { | |
| 304 /** @type {?string} */ | |
| 305 var string = null; | |
| 306 try { | |
| 307 string = /** @type {string} */ (this.result); | |
| 308 } catch (e) { | |
| 309 console.error('Can\'t read file: ' + path + ': ' + e); | |
| 310 } | |
| 311 callback(string); | |
| 312 } | |
| 313 | |
| 314 /** | |
| 315 * @this {Workspace.IsolatedFileSystem} | |
| 316 */ | |
| 317 function errorHandler(error) { | |
| 318 if (error.name === 'NotFoundError') { | |
| 319 callback(null); | |
| 320 return; | |
| 321 } | |
| 322 | |
| 323 var errorMessage = Workspace.IsolatedFileSystem.errorMessage(error); | |
| 324 console.error(errorMessage + ' when getting content for file \'' + (this._
path + '/' + path) + '\''); | |
| 325 callback(null); | |
| 326 } | |
| 327 } | |
| 328 | |
| 329 /** | |
| 330 * @param {string} path | |
| 331 * @param {string} content | |
| 332 * @param {function()} callback | |
| 333 */ | |
| 334 setFileContent(path, content, callback) { | |
| 335 Host.userMetrics.actionTaken(Host.UserMetrics.Action.FileSavedInWorkspace); | |
| 336 this._domFileSystem.root.getFile(path, {create: true}, fileEntryLoaded.bind(
this), errorHandler.bind(this)); | |
| 337 | |
| 338 /** | |
| 339 * @param {!FileEntry} entry | |
| 340 * @this {Workspace.IsolatedFileSystem} | |
| 341 */ | |
| 342 function fileEntryLoaded(entry) { | |
| 343 entry.createWriter(fileWriterCreated.bind(this), errorHandler.bind(this)); | |
| 344 } | |
| 345 | |
| 346 /** | |
| 347 * @param {!FileWriter} fileWriter | |
| 348 * @this {Workspace.IsolatedFileSystem} | |
| 349 */ | |
| 350 function fileWriterCreated(fileWriter) { | |
| 351 fileWriter.onerror = errorHandler.bind(this); | |
| 352 fileWriter.onwriteend = fileWritten; | |
| 353 var blob = new Blob([content], {type: 'text/plain'}); | |
| 354 fileWriter.write(blob); | |
| 355 | |
| 356 function fileWritten() { | |
| 357 fileWriter.onwriteend = callback; | |
| 358 fileWriter.truncate(blob.size); | |
| 359 } | |
| 360 } | |
| 361 | |
| 362 /** | |
| 363 * @this {Workspace.IsolatedFileSystem} | |
| 364 */ | |
| 365 function errorHandler(error) { | |
| 366 var errorMessage = Workspace.IsolatedFileSystem.errorMessage(error); | |
| 367 console.error(errorMessage + ' when setting content for file \'' + (this._
path + '/' + path) + '\''); | |
| 368 callback(); | |
| 369 } | |
| 370 } | |
| 371 | |
| 372 /** | |
| 373 * @param {string} path | |
| 374 * @param {string} newName | |
| 375 * @param {function(boolean, string=)} callback | |
| 376 */ | |
| 377 renameFile(path, newName, callback) { | |
| 378 newName = newName ? newName.trim() : newName; | |
| 379 if (!newName || newName.indexOf('/') !== -1) { | |
| 380 callback(false); | |
| 381 return; | |
| 382 } | |
| 383 var fileEntry; | |
| 384 var dirEntry; | |
| 385 | |
| 386 this._domFileSystem.root.getFile(path, undefined, fileEntryLoaded.bind(this)
, errorHandler.bind(this)); | |
| 387 | |
| 388 /** | |
| 389 * @param {!FileEntry} entry | |
| 390 * @this {Workspace.IsolatedFileSystem} | |
| 391 */ | |
| 392 function fileEntryLoaded(entry) { | |
| 393 if (entry.name === newName) { | |
| 394 callback(false); | |
| 395 return; | |
| 396 } | |
| 397 | |
| 398 fileEntry = entry; | |
| 399 fileEntry.getParent(dirEntryLoaded.bind(this), errorHandler.bind(this)); | |
| 400 } | |
| 401 | |
| 402 /** | |
| 403 * @param {!Entry} entry | |
| 404 * @this {Workspace.IsolatedFileSystem} | |
| 405 */ | |
| 406 function dirEntryLoaded(entry) { | |
| 407 dirEntry = entry; | |
| 408 dirEntry.getFile(newName, null, newFileEntryLoaded, newFileEntryLoadErrorH
andler.bind(this)); | |
| 409 } | |
| 410 | |
| 411 /** | |
| 412 * @param {!FileEntry} entry | |
| 413 */ | |
| 414 function newFileEntryLoaded(entry) { | |
| 415 callback(false); | |
| 416 } | |
| 417 | |
| 418 /** | |
| 419 * @this {Workspace.IsolatedFileSystem} | |
| 420 */ | |
| 421 function newFileEntryLoadErrorHandler(error) { | |
| 422 if (error.name !== 'NotFoundError') { | |
| 423 callback(false); | |
| 424 return; | |
| 425 } | |
| 426 fileEntry.moveTo(dirEntry, newName, fileRenamed, errorHandler.bind(this)); | |
| 427 } | |
| 428 | |
| 429 /** | |
| 430 * @param {!FileEntry} entry | |
| 431 */ | |
| 432 function fileRenamed(entry) { | |
| 433 callback(true, entry.name); | |
| 434 } | |
| 435 | |
| 436 /** | |
| 437 * @this {Workspace.IsolatedFileSystem} | |
| 438 */ | |
| 439 function errorHandler(error) { | |
| 440 var errorMessage = Workspace.IsolatedFileSystem.errorMessage(error); | |
| 441 console.error(errorMessage + ' when renaming file \'' + (this._path + '/'
+ path) + '\' to \'' + newName + '\''); | |
| 442 callback(false); | |
| 443 } | |
| 444 } | |
| 445 | |
| 446 /** | |
| 447 * @param {!DirectoryEntry} dirEntry | |
| 448 * @param {function(!Array.<!FileEntry>)} callback | |
| 449 */ | |
| 450 _readDirectory(dirEntry, callback) { | |
| 451 var dirReader = dirEntry.createReader(); | |
| 452 var entries = []; | |
| 453 | |
| 454 function innerCallback(results) { | |
| 455 if (!results.length) { | |
| 456 callback(entries.sort()); | |
| 457 } else { | |
| 458 entries = entries.concat(toArray(results)); | |
| 459 dirReader.readEntries(innerCallback, errorHandler); | |
| 460 } | |
| 461 } | |
| 462 | |
| 463 function toArray(list) { | |
| 464 return Array.prototype.slice.call(list || [], 0); | |
| 465 } | |
| 466 | |
| 467 dirReader.readEntries(innerCallback, errorHandler); | |
| 468 | |
| 469 function errorHandler(error) { | |
| 470 var errorMessage = Workspace.IsolatedFileSystem.errorMessage(error); | |
| 471 console.error(errorMessage + ' when reading directory \'' + dirEntry.fullP
ath + '\''); | |
| 472 callback([]); | |
| 473 } | |
| 474 } | |
| 475 | |
| 476 /** | |
| 477 * @param {string} path | |
| 478 * @param {function(!Array.<!FileEntry>)} callback | |
| 479 */ | |
| 480 _requestEntries(path, callback) { | |
| 481 this._domFileSystem.root.getDirectory(path, undefined, innerCallback.bind(th
is), errorHandler); | |
| 482 | |
| 483 /** | |
| 484 * @param {!DirectoryEntry} dirEntry | |
| 485 * @this {Workspace.IsolatedFileSystem} | |
| 486 */ | |
| 487 function innerCallback(dirEntry) { | |
| 488 this._readDirectory(dirEntry, callback); | |
| 489 } | |
| 490 | |
| 491 function errorHandler(error) { | |
| 492 var errorMessage = Workspace.IsolatedFileSystem.errorMessage(error); | |
| 493 console.error(errorMessage + ' when requesting entry \'' + path + '\''); | |
| 494 callback([]); | |
| 495 } | |
| 496 } | |
| 497 | |
| 498 _saveExcludedFolders() { | |
| 499 var settingValue = this._excludedFoldersSetting.get(); | |
| 500 settingValue[this._path] = this._excludedFolders.valuesArray(); | |
| 501 this._excludedFoldersSetting.set(settingValue); | |
| 502 } | |
| 503 | |
| 504 /** | |
| 505 * @param {string} path | |
| 506 */ | |
| 507 addExcludedFolder(path) { | |
| 508 this._excludedFolders.add(path); | |
| 509 this._saveExcludedFolders(); | |
| 510 this._manager.dispatchEventToListeners(Workspace.IsolatedFileSystemManager.E
vents.ExcludedFolderAdded, path); | |
| 511 } | |
| 512 | |
| 513 /** | |
| 514 * @param {string} path | |
| 515 */ | |
| 516 removeExcludedFolder(path) { | |
| 517 this._excludedFolders.delete(path); | |
| 518 this._saveExcludedFolders(); | |
| 519 this._manager.dispatchEventToListeners(Workspace.IsolatedFileSystemManager.E
vents.ExcludedFolderRemoved, path); | |
| 520 } | |
| 521 | |
| 522 fileSystemRemoved() { | |
| 523 var settingValue = this._excludedFoldersSetting.get(); | |
| 524 delete settingValue[this._path]; | |
| 525 this._excludedFoldersSetting.set(settingValue); | |
| 526 } | |
| 527 | |
| 528 /** | |
| 529 * @param {string} folderPath | |
| 530 * @return {boolean} | |
| 531 */ | |
| 532 _isFileExcluded(folderPath) { | |
| 533 if (this._excludedFolders.has(folderPath)) | |
| 534 return true; | |
| 535 var regex = this._manager.workspaceFolderExcludePatternSetting().asRegExp(); | |
| 536 return !!(regex && regex.test(folderPath)); | |
| 537 } | |
| 538 | |
| 539 /** | |
| 540 * @return {!Set<string>} | |
| 541 */ | |
| 542 excludedFolders() { | |
| 543 return this._excludedFolders; | |
| 544 } | |
| 545 | |
| 546 /** | |
| 547 * @param {string} query | |
| 548 * @param {!Common.Progress} progress | |
| 549 * @param {function(!Array.<string>)} callback | |
| 550 */ | |
| 551 searchInPath(query, progress, callback) { | |
| 552 var requestId = this._manager.registerCallback(innerCallback); | |
| 553 InspectorFrontendHost.searchInPath(requestId, this._embedderPath, query); | |
| 554 | |
| 555 /** | |
| 556 * @param {!Array.<string>} files | |
| 557 */ | |
| 558 function innerCallback(files) { | |
| 559 files = files.map(embedderPath => Common.ParsedURL.platformPathToURL(embed
derPath)); | |
| 560 progress.worked(1); | |
| 561 callback(files); | |
| 562 } | |
| 563 } | |
| 564 | |
| 565 /** | |
| 566 * @param {!Common.Progress} progress | |
| 567 */ | |
| 568 indexContent(progress) { | |
| 569 progress.setTotalWork(1); | |
| 570 var requestId = this._manager.registerProgress(progress); | |
| 571 InspectorFrontendHost.indexPath(requestId, this._embedderPath); | |
| 572 } | |
| 573 }; | |
| 574 | |
| 575 Workspace.IsolatedFileSystem.ImageExtensions = | |
| 576 new Set(['jpeg', 'jpg', 'svg', 'gif', 'webp', 'png', 'ico', 'tiff', 'tif', '
bmp']); | |
| OLD | NEW |