| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2013 Google Inc. All rights reserved. | 2 * Copyright (C) 2013 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 | 31 * @unrestricted |
| 33 * @param {!WebInspector.IsolatedFileSystemManager} manager | |
| 34 * @param {string} path | |
| 35 * @param {string} embedderPath | |
| 36 * @param {!DOMFileSystem} domFileSystem | |
| 37 */ | 32 */ |
| 38 WebInspector.IsolatedFileSystem = function(manager, path, embedderPath, domFileS
ystem) | 33 WebInspector.IsolatedFileSystem = class { |
| 39 { | 34 /** |
| 35 * @param {!WebInspector.IsolatedFileSystemManager} manager |
| 36 * @param {string} path |
| 37 * @param {string} embedderPath |
| 38 * @param {!DOMFileSystem} domFileSystem |
| 39 */ |
| 40 constructor(manager, path, embedderPath, domFileSystem) { |
| 40 this._manager = manager; | 41 this._manager = manager; |
| 41 this._path = path; | 42 this._path = path; |
| 42 this._embedderPath = embedderPath; | 43 this._embedderPath = embedderPath; |
| 43 this._domFileSystem = domFileSystem; | 44 this._domFileSystem = domFileSystem; |
| 44 this._excludedFoldersSetting = WebInspector.settings.createLocalSetting("wor
kspaceExcludedFolders", {}); | 45 this._excludedFoldersSetting = WebInspector.settings.createLocalSetting('wor
kspaceExcludedFolders', {}); |
| 45 /** @type {!Set<string>} */ | 46 /** @type {!Set<string>} */ |
| 46 this._excludedFolders = new Set(this._excludedFoldersSetting.get()[path] ||
[]); | 47 this._excludedFolders = new Set(this._excludedFoldersSetting.get()[path] ||
[]); |
| 47 /** @type {!Set<string>} */ | 48 /** @type {!Set<string>} */ |
| 48 this._nonConfigurableExcludedFolders = new Set(); | 49 this._nonConfigurableExcludedFolders = new Set(); |
| 49 | 50 |
| 50 /** @type {!Set<string>} */ | 51 /** @type {!Set<string>} */ |
| 51 this._filePaths = new Set(); | 52 this._filePaths = new Set(); |
| 52 /** @type {!Set<string>} */ | 53 /** @type {!Set<string>} */ |
| 53 this._gitFolders = new Set(); | 54 this._gitFolders = new Set(); |
| 54 }; | 55 } |
| 55 | 56 |
| 56 WebInspector.IsolatedFileSystem.ImageExtensions = new Set(["jpeg", "jpg", "svg",
"gif", "webp", "png", "ico", "tiff", "tif", "bmp"]); | 57 /** |
| 57 | 58 * @param {!WebInspector.IsolatedFileSystemManager} manager |
| 58 /** | 59 * @param {string} path |
| 59 * @constructor | 60 * @param {string} embedderPath |
| 60 * @param {!WebInspector.IsolatedFileSystemManager} manager | 61 * @param {string} name |
| 61 * @param {string} path | 62 * @param {string} rootURL |
| 62 * @param {string} embedderPath | 63 * @return {!Promise<?WebInspector.IsolatedFileSystem>} |
| 63 * @param {string} name | 64 */ |
| 64 * @param {string} rootURL | 65 static create(manager, path, embedderPath, name, rootURL) { |
| 65 * @return {!Promise<?WebInspector.IsolatedFileSystem>} | |
| 66 */ | |
| 67 WebInspector.IsolatedFileSystem.create = function(manager, path, embedderPath, n
ame, rootURL) | |
| 68 { | |
| 69 var domFileSystem = InspectorFrontendHost.isolatedFileSystem(name, rootURL); | 66 var domFileSystem = InspectorFrontendHost.isolatedFileSystem(name, rootURL); |
| 70 if (!domFileSystem) | 67 if (!domFileSystem) |
| 71 return Promise.resolve(/** @type {?WebInspector.IsolatedFileSystem} */(n
ull)); | 68 return Promise.resolve(/** @type {?WebInspector.IsolatedFileSystem} */ (nu
ll)); |
| 72 | 69 |
| 73 var fileSystem = new WebInspector.IsolatedFileSystem(manager, path, embedder
Path, domFileSystem); | 70 var fileSystem = new WebInspector.IsolatedFileSystem(manager, path, embedder
Path, domFileSystem); |
| 74 var fileContentPromise = fileSystem.requestFileContentPromise(".devtools"); | 71 var fileContentPromise = fileSystem.requestFileContentPromise('.devtools'); |
| 75 return fileContentPromise.then(onConfigAvailable) | 72 return fileContentPromise.then(onConfigAvailable) |
| 76 .then(() => fileSystem) | 73 .then(() => fileSystem) |
| 77 .catchException(/** @type {?WebInspector.IsolatedFileSystem} */(null)); | 74 .catchException(/** @type {?WebInspector.IsolatedFileSystem} */ (null)); |
| 78 | 75 |
| 79 /** | 76 /** |
| 80 * @param {?string} projectText | 77 * @param {?string} projectText |
| 81 * @return {!Promise} | 78 * @return {!Promise} |
| 82 */ | 79 */ |
| 83 function onConfigAvailable(projectText) | 80 function onConfigAvailable(projectText) { |
| 84 { | 81 if (projectText) { |
| 85 if (projectText) { | 82 try { |
| 86 try { | 83 var projectObject = JSON.parse(projectText); |
| 87 var projectObject = JSON.parse(projectText); | 84 fileSystem._initializeProject( |
| 88 fileSystem._initializeProject(typeof projectObject === "object"
? /** @type {!Object} */ (projectObject) : null); | 85 typeof projectObject === 'object' ? /** @type {!Object} */ (projec
tObject) : null); |
| 89 } catch (e) { | 86 } catch (e) { |
| 90 WebInspector.console.error("Invalid project file: " + projectTex
t); | 87 WebInspector.console.error('Invalid project file: ' + projectText); |
| 91 } | |
| 92 } | 88 } |
| 93 return fileSystem._initializeFilePaths(); | 89 } |
| 94 } | 90 return fileSystem._initializeFilePaths(); |
| 91 } |
| 92 } |
| 93 |
| 94 /** |
| 95 * @param {!DOMError} error |
| 96 * @return {string} |
| 97 */ |
| 98 static errorMessage(error) { |
| 99 return WebInspector.UIString('File system error: %s', error.message); |
| 100 } |
| 101 |
| 102 /** |
| 103 * @param {string} path |
| 104 * @return {!Promise<?{modificationTime: !Date, size: number}>} |
| 105 */ |
| 106 getMetadata(path) { |
| 107 var fulfill; |
| 108 var promise = new Promise(f => fulfill = f); |
| 109 this._domFileSystem.root.getFile(path, null, fileEntryLoaded, errorHandler); |
| 110 return promise; |
| 111 |
| 112 /** |
| 113 * @param {!FileEntry} entry |
| 114 */ |
| 115 function fileEntryLoaded(entry) { |
| 116 entry.getMetadata(fulfill, errorHandler); |
| 117 } |
| 118 |
| 119 /** |
| 120 * @param {!FileError} error |
| 121 */ |
| 122 function errorHandler(error) { |
| 123 var errorMessage = WebInspector.IsolatedFileSystem.errorMessage(error); |
| 124 console.error(errorMessage + ' when getting file metadata \'' + path); |
| 125 fulfill(null); |
| 126 } |
| 127 } |
| 128 |
| 129 /** |
| 130 * @return {!Array<string>} |
| 131 */ |
| 132 filePaths() { |
| 133 return this._filePaths.valuesArray(); |
| 134 } |
| 135 |
| 136 /** |
| 137 * @return {!Array<string>} |
| 138 */ |
| 139 gitFolders() { |
| 140 return this._gitFolders.valuesArray(); |
| 141 } |
| 142 |
| 143 /** |
| 144 * @return {string} |
| 145 */ |
| 146 path() { |
| 147 return this._path; |
| 148 } |
| 149 |
| 150 /** |
| 151 * @return {string} |
| 152 */ |
| 153 embedderPath() { |
| 154 return this._embedderPath; |
| 155 } |
| 156 |
| 157 /** |
| 158 * @param {?Object} projectObject |
| 159 */ |
| 160 _initializeProject(projectObject) { |
| 161 this._projectObject = projectObject; |
| 162 |
| 163 var projectExcludes = this.projectProperty('excludes'); |
| 164 if (Array.isArray(projectExcludes)) { |
| 165 for (var folder of /** @type {!Array<*>} */ (projectExcludes)) { |
| 166 if (typeof folder === 'string') |
| 167 this._nonConfigurableExcludedFolders.add(folder); |
| 168 } |
| 169 } |
| 170 } |
| 171 |
| 172 /** |
| 173 * @param {string} key |
| 174 * @return {*} |
| 175 */ |
| 176 projectProperty(key) { |
| 177 return this._projectObject ? this._projectObject[key] : null; |
| 178 } |
| 179 |
| 180 /** |
| 181 * @return {!Promise} |
| 182 */ |
| 183 _initializeFilePaths() { |
| 184 var fulfill; |
| 185 var promise = new Promise(x => fulfill = x); |
| 186 var pendingRequests = 1; |
| 187 var boundInnerCallback = innerCallback.bind(this); |
| 188 this._requestEntries('', boundInnerCallback); |
| 189 return promise; |
| 190 |
| 191 /** |
| 192 * @param {!Array.<!FileEntry>} entries |
| 193 * @this {WebInspector.IsolatedFileSystem} |
| 194 */ |
| 195 function innerCallback(entries) { |
| 196 for (var i = 0; i < entries.length; ++i) { |
| 197 var entry = entries[i]; |
| 198 if (!entry.isDirectory) { |
| 199 if (this._isFileExcluded(entry.fullPath)) |
| 200 continue; |
| 201 this._filePaths.add(entry.fullPath.substr(1)); |
| 202 } else { |
| 203 if (entry.fullPath.endsWith('/.git')) { |
| 204 var lastSlash = entry.fullPath.lastIndexOf('/'); |
| 205 var parentFolder = entry.fullPath.substring(1, lastSlash); |
| 206 this._gitFolders.add(parentFolder); |
| 207 } |
| 208 if (this._isFileExcluded(entry.fullPath + '/')) |
| 209 continue; |
| 210 ++pendingRequests; |
| 211 this._requestEntries(entry.fullPath, boundInnerCallback); |
| 212 } |
| 213 } |
| 214 if ((--pendingRequests === 0)) |
| 215 fulfill(); |
| 216 } |
| 217 } |
| 218 |
| 219 /** |
| 220 * @param {string} path |
| 221 * @param {?string} name |
| 222 * @param {function(?string)} callback |
| 223 */ |
| 224 createFile(path, name, callback) { |
| 225 var newFileIndex = 1; |
| 226 if (!name) |
| 227 name = 'NewFile'; |
| 228 var nameCandidate; |
| 229 |
| 230 this._domFileSystem.root.getDirectory(path, null, dirEntryLoaded.bind(this),
errorHandler.bind(this)); |
| 231 |
| 232 /** |
| 233 * @param {!DirectoryEntry} dirEntry |
| 234 * @this {WebInspector.IsolatedFileSystem} |
| 235 */ |
| 236 function dirEntryLoaded(dirEntry) { |
| 237 var nameCandidate = name; |
| 238 if (newFileIndex > 1) |
| 239 nameCandidate += newFileIndex; |
| 240 ++newFileIndex; |
| 241 dirEntry.getFile(nameCandidate, {create: true, exclusive: true}, fileCreat
ed, fileCreationError.bind(this)); |
| 242 |
| 243 function fileCreated(entry) { |
| 244 callback(entry.fullPath.substr(1)); |
| 245 } |
| 246 |
| 247 /** |
| 248 * @this {WebInspector.IsolatedFileSystem} |
| 249 */ |
| 250 function fileCreationError(error) { |
| 251 if (error.name === 'InvalidModificationError') { |
| 252 dirEntryLoaded.call(this, dirEntry); |
| 253 return; |
| 254 } |
| 255 |
| 256 var errorMessage = WebInspector.IsolatedFileSystem.errorMessage(error); |
| 257 console.error( |
| 258 errorMessage + ' when testing if file exists \'' + (this._path + '/'
+ path + '/' + nameCandidate) + '\''); |
| 259 callback(null); |
| 260 } |
| 261 } |
| 262 |
| 263 /** |
| 264 * @this {WebInspector.IsolatedFileSystem} |
| 265 */ |
| 266 function errorHandler(error) { |
| 267 var errorMessage = WebInspector.IsolatedFileSystem.errorMessage(error); |
| 268 var filePath = this._path + '/' + path; |
| 269 if (nameCandidate) |
| 270 filePath += '/' + nameCandidate; |
| 271 console.error(errorMessage + ' when getting content for file \'' + (filePa
th) + '\''); |
| 272 callback(null); |
| 273 } |
| 274 } |
| 275 |
| 276 /** |
| 277 * @param {string} path |
| 278 */ |
| 279 deleteFile(path) { |
| 280 this._domFileSystem.root.getFile(path, null, fileEntryLoaded.bind(this), err
orHandler.bind(this)); |
| 281 |
| 282 /** |
| 283 * @param {!FileEntry} fileEntry |
| 284 * @this {WebInspector.IsolatedFileSystem} |
| 285 */ |
| 286 function fileEntryLoaded(fileEntry) { |
| 287 fileEntry.remove(fileEntryRemoved, errorHandler.bind(this)); |
| 288 } |
| 289 |
| 290 function fileEntryRemoved() { |
| 291 } |
| 292 |
| 293 /** |
| 294 * @param {!FileError} error |
| 295 * @this {WebInspector.IsolatedFileSystem} |
| 296 * @suppress {checkTypes} |
| 297 * TODO(jsbell): Update externs replacing FileError with DOMException. https
://crbug.com/496901 |
| 298 */ |
| 299 function errorHandler(error) { |
| 300 var errorMessage = WebInspector.IsolatedFileSystem.errorMessage(error); |
| 301 console.error(errorMessage + ' when deleting file \'' + (this._path + '/'
+ path) + '\''); |
| 302 } |
| 303 } |
| 304 |
| 305 /** |
| 306 * @param {string} path |
| 307 * @return {!Promise<?string>} |
| 308 */ |
| 309 requestFileContentPromise(path) { |
| 310 var fulfill; |
| 311 var promise = new Promise(x => fulfill = x); |
| 312 this.requestFileContent(path, fulfill); |
| 313 return promise; |
| 314 } |
| 315 |
| 316 /** |
| 317 * @param {string} path |
| 318 * @param {function(?string)} callback |
| 319 */ |
| 320 requestFileContent(path, callback) { |
| 321 this._domFileSystem.root.getFile(path, null, fileEntryLoaded.bind(this), err
orHandler.bind(this)); |
| 322 |
| 323 /** |
| 324 * @param {!FileEntry} entry |
| 325 * @this {WebInspector.IsolatedFileSystem} |
| 326 */ |
| 327 function fileEntryLoaded(entry) { |
| 328 entry.file(fileLoaded, errorHandler.bind(this)); |
| 329 } |
| 330 |
| 331 /** |
| 332 * @param {!Blob} file |
| 333 */ |
| 334 function fileLoaded(file) { |
| 335 var reader = new FileReader(); |
| 336 reader.onloadend = readerLoadEnd; |
| 337 if (WebInspector.IsolatedFileSystem.ImageExtensions.has(WebInspector.Parse
dURL.extractExtension(path))) |
| 338 reader.readAsDataURL(file); |
| 339 else |
| 340 reader.readAsText(file); |
| 341 } |
| 342 |
| 343 /** |
| 344 * @this {!FileReader} |
| 345 */ |
| 346 function readerLoadEnd() { |
| 347 /** @type {?string} */ |
| 348 var string = null; |
| 349 try { |
| 350 string = /** @type {string} */ (this.result); |
| 351 } catch (e) { |
| 352 console.error('Can\'t read file: ' + path + ': ' + e); |
| 353 } |
| 354 callback(string); |
| 355 } |
| 356 |
| 357 /** |
| 358 * @this {WebInspector.IsolatedFileSystem} |
| 359 */ |
| 360 function errorHandler(error) { |
| 361 if (error.name === 'NotFoundError') { |
| 362 callback(null); |
| 363 return; |
| 364 } |
| 365 |
| 366 var errorMessage = WebInspector.IsolatedFileSystem.errorMessage(error); |
| 367 console.error(errorMessage + ' when getting content for file \'' + (this._
path + '/' + path) + '\''); |
| 368 callback(null); |
| 369 } |
| 370 } |
| 371 |
| 372 /** |
| 373 * @param {string} path |
| 374 * @param {string} content |
| 375 * @param {function()} callback |
| 376 */ |
| 377 setFileContent(path, content, callback) { |
| 378 WebInspector.userMetrics.actionTaken(WebInspector.UserMetrics.Action.FileSav
edInWorkspace); |
| 379 this._domFileSystem.root.getFile(path, {create: true}, fileEntryLoaded.bind(
this), errorHandler.bind(this)); |
| 380 |
| 381 /** |
| 382 * @param {!FileEntry} entry |
| 383 * @this {WebInspector.IsolatedFileSystem} |
| 384 */ |
| 385 function fileEntryLoaded(entry) { |
| 386 entry.createWriter(fileWriterCreated.bind(this), errorHandler.bind(this)); |
| 387 } |
| 388 |
| 389 /** |
| 390 * @param {!FileWriter} fileWriter |
| 391 * @this {WebInspector.IsolatedFileSystem} |
| 392 */ |
| 393 function fileWriterCreated(fileWriter) { |
| 394 fileWriter.onerror = errorHandler.bind(this); |
| 395 fileWriter.onwriteend = fileWritten; |
| 396 var blob = new Blob([content], {type: 'text/plain'}); |
| 397 fileWriter.write(blob); |
| 398 |
| 399 function fileWritten() { |
| 400 fileWriter.onwriteend = callback; |
| 401 fileWriter.truncate(blob.size); |
| 402 } |
| 403 } |
| 404 |
| 405 /** |
| 406 * @this {WebInspector.IsolatedFileSystem} |
| 407 */ |
| 408 function errorHandler(error) { |
| 409 var errorMessage = WebInspector.IsolatedFileSystem.errorMessage(error); |
| 410 console.error(errorMessage + ' when setting content for file \'' + (this._
path + '/' + path) + '\''); |
| 411 callback(); |
| 412 } |
| 413 } |
| 414 |
| 415 /** |
| 416 * @param {string} path |
| 417 * @param {string} newName |
| 418 * @param {function(boolean, string=)} callback |
| 419 */ |
| 420 renameFile(path, newName, callback) { |
| 421 newName = newName ? newName.trim() : newName; |
| 422 if (!newName || newName.indexOf('/') !== -1) { |
| 423 callback(false); |
| 424 return; |
| 425 } |
| 426 var fileEntry; |
| 427 var dirEntry; |
| 428 |
| 429 this._domFileSystem.root.getFile(path, null, fileEntryLoaded.bind(this), err
orHandler.bind(this)); |
| 430 |
| 431 /** |
| 432 * @param {!FileEntry} entry |
| 433 * @this {WebInspector.IsolatedFileSystem} |
| 434 */ |
| 435 function fileEntryLoaded(entry) { |
| 436 if (entry.name === newName) { |
| 437 callback(false); |
| 438 return; |
| 439 } |
| 440 |
| 441 fileEntry = entry; |
| 442 fileEntry.getParent(dirEntryLoaded.bind(this), errorHandler.bind(this)); |
| 443 } |
| 444 |
| 445 /** |
| 446 * @param {!Entry} entry |
| 447 * @this {WebInspector.IsolatedFileSystem} |
| 448 */ |
| 449 function dirEntryLoaded(entry) { |
| 450 dirEntry = entry; |
| 451 dirEntry.getFile(newName, null, newFileEntryLoaded, newFileEntryLoadErrorH
andler.bind(this)); |
| 452 } |
| 453 |
| 454 /** |
| 455 * @param {!FileEntry} entry |
| 456 */ |
| 457 function newFileEntryLoaded(entry) { |
| 458 callback(false); |
| 459 } |
| 460 |
| 461 /** |
| 462 * @this {WebInspector.IsolatedFileSystem} |
| 463 */ |
| 464 function newFileEntryLoadErrorHandler(error) { |
| 465 if (error.name !== 'NotFoundError') { |
| 466 callback(false); |
| 467 return; |
| 468 } |
| 469 fileEntry.moveTo(dirEntry, newName, fileRenamed, errorHandler.bind(this)); |
| 470 } |
| 471 |
| 472 /** |
| 473 * @param {!FileEntry} entry |
| 474 */ |
| 475 function fileRenamed(entry) { |
| 476 callback(true, entry.name); |
| 477 } |
| 478 |
| 479 /** |
| 480 * @this {WebInspector.IsolatedFileSystem} |
| 481 */ |
| 482 function errorHandler(error) { |
| 483 var errorMessage = WebInspector.IsolatedFileSystem.errorMessage(error); |
| 484 console.error(errorMessage + ' when renaming file \'' + (this._path + '/'
+ path) + '\' to \'' + newName + '\''); |
| 485 callback(false); |
| 486 } |
| 487 } |
| 488 |
| 489 /** |
| 490 * @param {!DirectoryEntry} dirEntry |
| 491 * @param {function(!Array.<!FileEntry>)} callback |
| 492 */ |
| 493 _readDirectory(dirEntry, callback) { |
| 494 var dirReader = dirEntry.createReader(); |
| 495 var entries = []; |
| 496 |
| 497 function innerCallback(results) { |
| 498 if (!results.length) { |
| 499 callback(entries.sort()); |
| 500 } else { |
| 501 entries = entries.concat(toArray(results)); |
| 502 dirReader.readEntries(innerCallback, errorHandler); |
| 503 } |
| 504 } |
| 505 |
| 506 function toArray(list) { |
| 507 return Array.prototype.slice.call(list || [], 0); |
| 508 } |
| 509 |
| 510 dirReader.readEntries(innerCallback, errorHandler); |
| 511 |
| 512 function errorHandler(error) { |
| 513 var errorMessage = WebInspector.IsolatedFileSystem.errorMessage(error); |
| 514 console.error(errorMessage + ' when reading directory \'' + dirEntry.fullP
ath + '\''); |
| 515 callback([]); |
| 516 } |
| 517 } |
| 518 |
| 519 /** |
| 520 * @param {string} path |
| 521 * @param {function(!Array.<!FileEntry>)} callback |
| 522 */ |
| 523 _requestEntries(path, callback) { |
| 524 this._domFileSystem.root.getDirectory(path, null, innerCallback.bind(this),
errorHandler); |
| 525 |
| 526 /** |
| 527 * @param {!DirectoryEntry} dirEntry |
| 528 * @this {WebInspector.IsolatedFileSystem} |
| 529 */ |
| 530 function innerCallback(dirEntry) { |
| 531 this._readDirectory(dirEntry, callback); |
| 532 } |
| 533 |
| 534 function errorHandler(error) { |
| 535 var errorMessage = WebInspector.IsolatedFileSystem.errorMessage(error); |
| 536 console.error(errorMessage + ' when requesting entry \'' + path + '\''); |
| 537 callback([]); |
| 538 } |
| 539 } |
| 540 |
| 541 _saveExcludedFolders() { |
| 542 var settingValue = this._excludedFoldersSetting.get(); |
| 543 settingValue[this._path] = this._excludedFolders.valuesArray(); |
| 544 this._excludedFoldersSetting.set(settingValue); |
| 545 } |
| 546 |
| 547 /** |
| 548 * @param {string} path |
| 549 */ |
| 550 addExcludedFolder(path) { |
| 551 this._excludedFolders.add(path); |
| 552 this._saveExcludedFolders(); |
| 553 this._manager.dispatchEventToListeners(WebInspector.IsolatedFileSystemManage
r.Events.ExcludedFolderAdded, path); |
| 554 } |
| 555 |
| 556 /** |
| 557 * @param {string} path |
| 558 */ |
| 559 removeExcludedFolder(path) { |
| 560 this._excludedFolders.delete(path); |
| 561 this._saveExcludedFolders(); |
| 562 this._manager.dispatchEventToListeners(WebInspector.IsolatedFileSystemManage
r.Events.ExcludedFolderRemoved, path); |
| 563 } |
| 564 |
| 565 fileSystemRemoved() { |
| 566 var settingValue = this._excludedFoldersSetting.get(); |
| 567 delete settingValue[this._path]; |
| 568 this._excludedFoldersSetting.set(settingValue); |
| 569 } |
| 570 |
| 571 /** |
| 572 * @param {string} folderPath |
| 573 * @return {boolean} |
| 574 */ |
| 575 _isFileExcluded(folderPath) { |
| 576 if (this._nonConfigurableExcludedFolders.has(folderPath) || this._excludedFo
lders.has(folderPath)) |
| 577 return true; |
| 578 var regex = this._manager.workspaceFolderExcludePatternSetting().asRegExp(); |
| 579 return !!(regex && regex.test(folderPath)); |
| 580 } |
| 581 |
| 582 /** |
| 583 * @return {!Set<string>} |
| 584 */ |
| 585 excludedFolders() { |
| 586 return this._excludedFolders; |
| 587 } |
| 588 |
| 589 /** |
| 590 * @return {!Set<string>} |
| 591 */ |
| 592 nonConfigurableExcludedFolders() { |
| 593 return this._nonConfigurableExcludedFolders; |
| 594 } |
| 595 |
| 596 /** |
| 597 * @param {string} query |
| 598 * @param {!WebInspector.Progress} progress |
| 599 * @param {function(!Array.<string>)} callback |
| 600 */ |
| 601 searchInPath(query, progress, callback) { |
| 602 var requestId = this._manager.registerCallback(innerCallback); |
| 603 InspectorFrontendHost.searchInPath(requestId, this._embedderPath, query); |
| 604 |
| 605 /** |
| 606 * @param {!Array.<string>} files |
| 607 */ |
| 608 function innerCallback(files) { |
| 609 files = files.map(embedderPath => WebInspector.ParsedURL.platformPathToURL
(embedderPath)); |
| 610 progress.worked(1); |
| 611 callback(files); |
| 612 } |
| 613 } |
| 614 |
| 615 /** |
| 616 * @param {!WebInspector.Progress} progress |
| 617 */ |
| 618 indexContent(progress) { |
| 619 progress.setTotalWork(1); |
| 620 var requestId = this._manager.registerProgress(progress); |
| 621 InspectorFrontendHost.indexPath(requestId, this._embedderPath); |
| 622 } |
| 95 }; | 623 }; |
| 96 | 624 |
| 97 /** | 625 WebInspector.IsolatedFileSystem.ImageExtensions = |
| 98 * @param {!DOMError} error | 626 new Set(['jpeg', 'jpg', 'svg', 'gif', 'webp', 'png', 'ico', 'tiff', 'tif', '
bmp']); |
| 99 * @return {string} | 627 |
| 100 */ | 628 |
| 101 WebInspector.IsolatedFileSystem.errorMessage = function(error) | |
| 102 { | |
| 103 return WebInspector.UIString("File system error: %s", error.message); | |
| 104 }; | |
| 105 | |
| 106 WebInspector.IsolatedFileSystem.prototype = { | |
| 107 /** | |
| 108 * @param {string} path | |
| 109 * @return {!Promise<?{modificationTime: !Date, size: number}>} | |
| 110 */ | |
| 111 getMetadata: function(path) | |
| 112 { | |
| 113 var fulfill; | |
| 114 var promise = new Promise(f => fulfill = f); | |
| 115 this._domFileSystem.root.getFile(path, null, fileEntryLoaded, errorHandl
er); | |
| 116 return promise; | |
| 117 | |
| 118 /** | |
| 119 * @param {!FileEntry} entry | |
| 120 */ | |
| 121 function fileEntryLoaded(entry) | |
| 122 { | |
| 123 entry.getMetadata(fulfill, errorHandler); | |
| 124 } | |
| 125 | |
| 126 /** | |
| 127 * @param {!FileError} error | |
| 128 */ | |
| 129 function errorHandler(error) | |
| 130 { | |
| 131 var errorMessage = WebInspector.IsolatedFileSystem.errorMessage(erro
r); | |
| 132 console.error(errorMessage + " when getting file metadata '" + path)
; | |
| 133 fulfill(null); | |
| 134 } | |
| 135 }, | |
| 136 | |
| 137 /** | |
| 138 * @return {!Array<string>} | |
| 139 */ | |
| 140 filePaths: function() | |
| 141 { | |
| 142 return this._filePaths.valuesArray(); | |
| 143 }, | |
| 144 | |
| 145 /** | |
| 146 * @return {!Array<string>} | |
| 147 */ | |
| 148 gitFolders: function() | |
| 149 { | |
| 150 return this._gitFolders.valuesArray(); | |
| 151 }, | |
| 152 | |
| 153 /** | |
| 154 * @return {string} | |
| 155 */ | |
| 156 path: function() | |
| 157 { | |
| 158 return this._path; | |
| 159 }, | |
| 160 | |
| 161 /** | |
| 162 * @return {string} | |
| 163 */ | |
| 164 embedderPath: function() | |
| 165 { | |
| 166 return this._embedderPath; | |
| 167 }, | |
| 168 | |
| 169 /** | |
| 170 * @param {?Object} projectObject | |
| 171 */ | |
| 172 _initializeProject: function(projectObject) | |
| 173 { | |
| 174 this._projectObject = projectObject; | |
| 175 | |
| 176 var projectExcludes = this.projectProperty("excludes"); | |
| 177 if (Array.isArray(projectExcludes)) { | |
| 178 for (var folder of /** @type {!Array<*>} */ (projectExcludes)) { | |
| 179 if (typeof folder === "string") | |
| 180 this._nonConfigurableExcludedFolders.add(folder); | |
| 181 } | |
| 182 } | |
| 183 }, | |
| 184 | |
| 185 /** | |
| 186 * @param {string} key | |
| 187 * @return {*} | |
| 188 */ | |
| 189 projectProperty: function(key) | |
| 190 { | |
| 191 return this._projectObject ? this._projectObject[key] : null; | |
| 192 }, | |
| 193 | |
| 194 /** | |
| 195 * @return {!Promise} | |
| 196 */ | |
| 197 _initializeFilePaths: function() | |
| 198 { | |
| 199 var fulfill; | |
| 200 var promise = new Promise(x => fulfill = x); | |
| 201 var pendingRequests = 1; | |
| 202 var boundInnerCallback = innerCallback.bind(this); | |
| 203 this._requestEntries("", boundInnerCallback); | |
| 204 return promise; | |
| 205 | |
| 206 /** | |
| 207 * @param {!Array.<!FileEntry>} entries | |
| 208 * @this {WebInspector.IsolatedFileSystem} | |
| 209 */ | |
| 210 function innerCallback(entries) | |
| 211 { | |
| 212 for (var i = 0; i < entries.length; ++i) { | |
| 213 var entry = entries[i]; | |
| 214 if (!entry.isDirectory) { | |
| 215 if (this._isFileExcluded(entry.fullPath)) | |
| 216 continue; | |
| 217 this._filePaths.add(entry.fullPath.substr(1)); | |
| 218 } else { | |
| 219 if (entry.fullPath.endsWith("/.git")) { | |
| 220 var lastSlash = entry.fullPath.lastIndexOf("/"); | |
| 221 var parentFolder = entry.fullPath.substring(1, lastSlash
); | |
| 222 this._gitFolders.add(parentFolder); | |
| 223 } | |
| 224 if (this._isFileExcluded(entry.fullPath + "/")) | |
| 225 continue; | |
| 226 ++pendingRequests; | |
| 227 this._requestEntries(entry.fullPath, boundInnerCallback); | |
| 228 } | |
| 229 } | |
| 230 if ((--pendingRequests === 0)) | |
| 231 fulfill(); | |
| 232 } | |
| 233 }, | |
| 234 | |
| 235 /** | |
| 236 * @param {string} path | |
| 237 * @param {?string} name | |
| 238 * @param {function(?string)} callback | |
| 239 */ | |
| 240 createFile: function(path, name, callback) | |
| 241 { | |
| 242 var newFileIndex = 1; | |
| 243 if (!name) | |
| 244 name = "NewFile"; | |
| 245 var nameCandidate; | |
| 246 | |
| 247 this._domFileSystem.root.getDirectory(path, null, dirEntryLoaded.bind(th
is), errorHandler.bind(this)); | |
| 248 | |
| 249 /** | |
| 250 * @param {!DirectoryEntry} dirEntry | |
| 251 * @this {WebInspector.IsolatedFileSystem} | |
| 252 */ | |
| 253 function dirEntryLoaded(dirEntry) | |
| 254 { | |
| 255 var nameCandidate = name; | |
| 256 if (newFileIndex > 1) | |
| 257 nameCandidate += newFileIndex; | |
| 258 ++newFileIndex; | |
| 259 dirEntry.getFile(nameCandidate, { create: true, exclusive: true }, f
ileCreated, fileCreationError.bind(this)); | |
| 260 | |
| 261 function fileCreated(entry) | |
| 262 { | |
| 263 callback(entry.fullPath.substr(1)); | |
| 264 } | |
| 265 | |
| 266 /** | |
| 267 * @this {WebInspector.IsolatedFileSystem} | |
| 268 */ | |
| 269 function fileCreationError(error) | |
| 270 { | |
| 271 if (error.name === "InvalidModificationError") { | |
| 272 dirEntryLoaded.call(this, dirEntry); | |
| 273 return; | |
| 274 } | |
| 275 | |
| 276 var errorMessage = WebInspector.IsolatedFileSystem.errorMessage(
error); | |
| 277 console.error(errorMessage + " when testing if file exists '" +
(this._path + "/" + path + "/" + nameCandidate) + "'"); | |
| 278 callback(null); | |
| 279 } | |
| 280 } | |
| 281 | |
| 282 /** | |
| 283 * @this {WebInspector.IsolatedFileSystem} | |
| 284 */ | |
| 285 function errorHandler(error) | |
| 286 { | |
| 287 var errorMessage = WebInspector.IsolatedFileSystem.errorMessage(erro
r); | |
| 288 var filePath = this._path + "/" + path; | |
| 289 if (nameCandidate) | |
| 290 filePath += "/" + nameCandidate; | |
| 291 console.error(errorMessage + " when getting content for file '" + (f
ilePath) + "'"); | |
| 292 callback(null); | |
| 293 } | |
| 294 }, | |
| 295 | |
| 296 /** | |
| 297 * @param {string} path | |
| 298 */ | |
| 299 deleteFile: function(path) | |
| 300 { | |
| 301 this._domFileSystem.root.getFile(path, null, fileEntryLoaded.bind(this),
errorHandler.bind(this)); | |
| 302 | |
| 303 /** | |
| 304 * @param {!FileEntry} fileEntry | |
| 305 * @this {WebInspector.IsolatedFileSystem} | |
| 306 */ | |
| 307 function fileEntryLoaded(fileEntry) | |
| 308 { | |
| 309 fileEntry.remove(fileEntryRemoved, errorHandler.bind(this)); | |
| 310 } | |
| 311 | |
| 312 function fileEntryRemoved() | |
| 313 { | |
| 314 } | |
| 315 | |
| 316 /** | |
| 317 * @param {!FileError} error | |
| 318 * @this {WebInspector.IsolatedFileSystem} | |
| 319 * @suppress {checkTypes} | |
| 320 * TODO(jsbell): Update externs replacing FileError with DOMException. h
ttps://crbug.com/496901 | |
| 321 */ | |
| 322 function errorHandler(error) | |
| 323 { | |
| 324 var errorMessage = WebInspector.IsolatedFileSystem.errorMessage(erro
r); | |
| 325 console.error(errorMessage + " when deleting file '" + (this._path +
"/" + path) + "'"); | |
| 326 } | |
| 327 }, | |
| 328 | |
| 329 /** | |
| 330 * @param {string} path | |
| 331 * @return {!Promise<?string>} | |
| 332 */ | |
| 333 requestFileContentPromise: function(path) | |
| 334 { | |
| 335 var fulfill; | |
| 336 var promise = new Promise(x => fulfill = x); | |
| 337 this.requestFileContent(path, fulfill); | |
| 338 return promise; | |
| 339 }, | |
| 340 | |
| 341 /** | |
| 342 * @param {string} path | |
| 343 * @param {function(?string)} callback | |
| 344 */ | |
| 345 requestFileContent: function(path, callback) | |
| 346 { | |
| 347 this._domFileSystem.root.getFile(path, null, fileEntryLoaded.bind(this),
errorHandler.bind(this)); | |
| 348 | |
| 349 /** | |
| 350 * @param {!FileEntry} entry | |
| 351 * @this {WebInspector.IsolatedFileSystem} | |
| 352 */ | |
| 353 function fileEntryLoaded(entry) | |
| 354 { | |
| 355 entry.file(fileLoaded, errorHandler.bind(this)); | |
| 356 } | |
| 357 | |
| 358 /** | |
| 359 * @param {!Blob} file | |
| 360 */ | |
| 361 function fileLoaded(file) | |
| 362 { | |
| 363 var reader = new FileReader(); | |
| 364 reader.onloadend = readerLoadEnd; | |
| 365 if (WebInspector.IsolatedFileSystem.ImageExtensions.has(WebInspector
.ParsedURL.extractExtension(path))) | |
| 366 reader.readAsDataURL(file); | |
| 367 else | |
| 368 reader.readAsText(file); | |
| 369 } | |
| 370 | |
| 371 /** | |
| 372 * @this {!FileReader} | |
| 373 */ | |
| 374 function readerLoadEnd() | |
| 375 { | |
| 376 /** @type {?string} */ | |
| 377 var string = null; | |
| 378 try { | |
| 379 string = /** @type {string} */ (this.result); | |
| 380 } catch (e) { | |
| 381 console.error("Can't read file: " + path + ": " + e); | |
| 382 } | |
| 383 callback(string); | |
| 384 } | |
| 385 | |
| 386 /** | |
| 387 * @this {WebInspector.IsolatedFileSystem} | |
| 388 */ | |
| 389 function errorHandler(error) | |
| 390 { | |
| 391 if (error.name === "NotFoundError") { | |
| 392 callback(null); | |
| 393 return; | |
| 394 } | |
| 395 | |
| 396 var errorMessage = WebInspector.IsolatedFileSystem.errorMessage(erro
r); | |
| 397 console.error(errorMessage + " when getting content for file '" + (t
his._path + "/" + path) + "'"); | |
| 398 callback(null); | |
| 399 } | |
| 400 }, | |
| 401 | |
| 402 /** | |
| 403 * @param {string} path | |
| 404 * @param {string} content | |
| 405 * @param {function()} callback | |
| 406 */ | |
| 407 setFileContent: function(path, content, callback) | |
| 408 { | |
| 409 WebInspector.userMetrics.actionTaken(WebInspector.UserMetrics.Action.Fil
eSavedInWorkspace); | |
| 410 this._domFileSystem.root.getFile(path, { create: true }, fileEntryLoaded
.bind(this), errorHandler.bind(this)); | |
| 411 | |
| 412 /** | |
| 413 * @param {!FileEntry} entry | |
| 414 * @this {WebInspector.IsolatedFileSystem} | |
| 415 */ | |
| 416 function fileEntryLoaded(entry) | |
| 417 { | |
| 418 entry.createWriter(fileWriterCreated.bind(this), errorHandler.bind(t
his)); | |
| 419 } | |
| 420 | |
| 421 /** | |
| 422 * @param {!FileWriter} fileWriter | |
| 423 * @this {WebInspector.IsolatedFileSystem} | |
| 424 */ | |
| 425 function fileWriterCreated(fileWriter) | |
| 426 { | |
| 427 fileWriter.onerror = errorHandler.bind(this); | |
| 428 fileWriter.onwriteend = fileWritten; | |
| 429 var blob = new Blob([content], { type: "text/plain" }); | |
| 430 fileWriter.write(blob); | |
| 431 | |
| 432 function fileWritten() | |
| 433 { | |
| 434 fileWriter.onwriteend = callback; | |
| 435 fileWriter.truncate(blob.size); | |
| 436 } | |
| 437 } | |
| 438 | |
| 439 /** | |
| 440 * @this {WebInspector.IsolatedFileSystem} | |
| 441 */ | |
| 442 function errorHandler(error) | |
| 443 { | |
| 444 var errorMessage = WebInspector.IsolatedFileSystem.errorMessage(erro
r); | |
| 445 console.error(errorMessage + " when setting content for file '" + (t
his._path + "/" + path) + "'"); | |
| 446 callback(); | |
| 447 } | |
| 448 }, | |
| 449 | |
| 450 /** | |
| 451 * @param {string} path | |
| 452 * @param {string} newName | |
| 453 * @param {function(boolean, string=)} callback | |
| 454 */ | |
| 455 renameFile: function(path, newName, callback) | |
| 456 { | |
| 457 newName = newName ? newName.trim() : newName; | |
| 458 if (!newName || newName.indexOf("/") !== -1) { | |
| 459 callback(false); | |
| 460 return; | |
| 461 } | |
| 462 var fileEntry; | |
| 463 var dirEntry; | |
| 464 | |
| 465 this._domFileSystem.root.getFile(path, null, fileEntryLoaded.bind(this),
errorHandler.bind(this)); | |
| 466 | |
| 467 /** | |
| 468 * @param {!FileEntry} entry | |
| 469 * @this {WebInspector.IsolatedFileSystem} | |
| 470 */ | |
| 471 function fileEntryLoaded(entry) | |
| 472 { | |
| 473 if (entry.name === newName) { | |
| 474 callback(false); | |
| 475 return; | |
| 476 } | |
| 477 | |
| 478 fileEntry = entry; | |
| 479 fileEntry.getParent(dirEntryLoaded.bind(this), errorHandler.bind(thi
s)); | |
| 480 } | |
| 481 | |
| 482 /** | |
| 483 * @param {!Entry} entry | |
| 484 * @this {WebInspector.IsolatedFileSystem} | |
| 485 */ | |
| 486 function dirEntryLoaded(entry) | |
| 487 { | |
| 488 dirEntry = entry; | |
| 489 dirEntry.getFile(newName, null, newFileEntryLoaded, newFileEntryLoad
ErrorHandler.bind(this)); | |
| 490 } | |
| 491 | |
| 492 /** | |
| 493 * @param {!FileEntry} entry | |
| 494 */ | |
| 495 function newFileEntryLoaded(entry) | |
| 496 { | |
| 497 callback(false); | |
| 498 } | |
| 499 | |
| 500 /** | |
| 501 * @this {WebInspector.IsolatedFileSystem} | |
| 502 */ | |
| 503 function newFileEntryLoadErrorHandler(error) | |
| 504 { | |
| 505 if (error.name !== "NotFoundError") { | |
| 506 callback(false); | |
| 507 return; | |
| 508 } | |
| 509 fileEntry.moveTo(dirEntry, newName, fileRenamed, errorHandler.bind(t
his)); | |
| 510 } | |
| 511 | |
| 512 /** | |
| 513 * @param {!FileEntry} entry | |
| 514 */ | |
| 515 function fileRenamed(entry) | |
| 516 { | |
| 517 callback(true, entry.name); | |
| 518 } | |
| 519 | |
| 520 /** | |
| 521 * @this {WebInspector.IsolatedFileSystem} | |
| 522 */ | |
| 523 function errorHandler(error) | |
| 524 { | |
| 525 var errorMessage = WebInspector.IsolatedFileSystem.errorMessage(erro
r); | |
| 526 console.error(errorMessage + " when renaming file '" + (this._path +
"/" + path) + "' to '" + newName + "'"); | |
| 527 callback(false); | |
| 528 } | |
| 529 }, | |
| 530 | |
| 531 /** | |
| 532 * @param {!DirectoryEntry} dirEntry | |
| 533 * @param {function(!Array.<!FileEntry>)} callback | |
| 534 */ | |
| 535 _readDirectory: function(dirEntry, callback) | |
| 536 { | |
| 537 var dirReader = dirEntry.createReader(); | |
| 538 var entries = []; | |
| 539 | |
| 540 function innerCallback(results) | |
| 541 { | |
| 542 if (!results.length) { | |
| 543 callback(entries.sort()); | |
| 544 } else { | |
| 545 entries = entries.concat(toArray(results)); | |
| 546 dirReader.readEntries(innerCallback, errorHandler); | |
| 547 } | |
| 548 } | |
| 549 | |
| 550 function toArray(list) | |
| 551 { | |
| 552 return Array.prototype.slice.call(list || [], 0); | |
| 553 } | |
| 554 | |
| 555 dirReader.readEntries(innerCallback, errorHandler); | |
| 556 | |
| 557 function errorHandler(error) | |
| 558 { | |
| 559 var errorMessage = WebInspector.IsolatedFileSystem.errorMessage(erro
r); | |
| 560 console.error(errorMessage + " when reading directory '" + dirEntry.
fullPath + "'"); | |
| 561 callback([]); | |
| 562 } | |
| 563 }, | |
| 564 | |
| 565 /** | |
| 566 * @param {string} path | |
| 567 * @param {function(!Array.<!FileEntry>)} callback | |
| 568 */ | |
| 569 _requestEntries: function(path, callback) | |
| 570 { | |
| 571 this._domFileSystem.root.getDirectory(path, null, innerCallback.bind(thi
s), errorHandler); | |
| 572 | |
| 573 /** | |
| 574 * @param {!DirectoryEntry} dirEntry | |
| 575 * @this {WebInspector.IsolatedFileSystem} | |
| 576 */ | |
| 577 function innerCallback(dirEntry) | |
| 578 { | |
| 579 this._readDirectory(dirEntry, callback); | |
| 580 } | |
| 581 | |
| 582 function errorHandler(error) | |
| 583 { | |
| 584 var errorMessage = WebInspector.IsolatedFileSystem.errorMessage(erro
r); | |
| 585 console.error(errorMessage + " when requesting entry '" + path + "'"
); | |
| 586 callback([]); | |
| 587 } | |
| 588 }, | |
| 589 | |
| 590 _saveExcludedFolders: function() | |
| 591 { | |
| 592 var settingValue = this._excludedFoldersSetting.get(); | |
| 593 settingValue[this._path] = this._excludedFolders.valuesArray(); | |
| 594 this._excludedFoldersSetting.set(settingValue); | |
| 595 }, | |
| 596 | |
| 597 /** | |
| 598 * @param {string} path | |
| 599 */ | |
| 600 addExcludedFolder: function(path) | |
| 601 { | |
| 602 this._excludedFolders.add(path); | |
| 603 this._saveExcludedFolders(); | |
| 604 this._manager.dispatchEventToListeners(WebInspector.IsolatedFileSystemMa
nager.Events.ExcludedFolderAdded, path); | |
| 605 }, | |
| 606 | |
| 607 /** | |
| 608 * @param {string} path | |
| 609 */ | |
| 610 removeExcludedFolder: function(path) | |
| 611 { | |
| 612 this._excludedFolders.delete(path); | |
| 613 this._saveExcludedFolders(); | |
| 614 this._manager.dispatchEventToListeners(WebInspector.IsolatedFileSystemMa
nager.Events.ExcludedFolderRemoved, path); | |
| 615 }, | |
| 616 | |
| 617 fileSystemRemoved: function() | |
| 618 { | |
| 619 var settingValue = this._excludedFoldersSetting.get(); | |
| 620 delete settingValue[this._path]; | |
| 621 this._excludedFoldersSetting.set(settingValue); | |
| 622 }, | |
| 623 | |
| 624 /** | |
| 625 * @param {string} folderPath | |
| 626 * @return {boolean} | |
| 627 */ | |
| 628 _isFileExcluded: function(folderPath) | |
| 629 { | |
| 630 if (this._nonConfigurableExcludedFolders.has(folderPath) || this._exclud
edFolders.has(folderPath)) | |
| 631 return true; | |
| 632 var regex = this._manager.workspaceFolderExcludePatternSetting().asRegEx
p(); | |
| 633 return !!(regex && regex.test(folderPath)); | |
| 634 }, | |
| 635 | |
| 636 /** | |
| 637 * @return {!Set<string>} | |
| 638 */ | |
| 639 excludedFolders: function() | |
| 640 { | |
| 641 return this._excludedFolders; | |
| 642 }, | |
| 643 | |
| 644 /** | |
| 645 * @return {!Set<string>} | |
| 646 */ | |
| 647 nonConfigurableExcludedFolders: function() | |
| 648 { | |
| 649 return this._nonConfigurableExcludedFolders; | |
| 650 }, | |
| 651 | |
| 652 /** | |
| 653 * @param {string} query | |
| 654 * @param {!WebInspector.Progress} progress | |
| 655 * @param {function(!Array.<string>)} callback | |
| 656 */ | |
| 657 searchInPath: function(query, progress, callback) | |
| 658 { | |
| 659 var requestId = this._manager.registerCallback(innerCallback); | |
| 660 InspectorFrontendHost.searchInPath(requestId, this._embedderPath, query)
; | |
| 661 | |
| 662 /** | |
| 663 * @param {!Array.<string>} files | |
| 664 */ | |
| 665 function innerCallback(files) | |
| 666 { | |
| 667 files = files.map(embedderPath => WebInspector.ParsedURL.platformPat
hToURL(embedderPath)); | |
| 668 progress.worked(1); | |
| 669 callback(files); | |
| 670 } | |
| 671 }, | |
| 672 | |
| 673 /** | |
| 674 * @param {!WebInspector.Progress} progress | |
| 675 */ | |
| 676 indexContent: function(progress) | |
| 677 { | |
| 678 progress.setTotalWork(1); | |
| 679 var requestId = this._manager.registerProgress(progress); | |
| 680 InspectorFrontendHost.indexPath(requestId, this._embedderPath); | |
| 681 } | |
| 682 }; | |
| OLD | NEW |