Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(152)

Side by Side Diff: Source/devtools/front_end/sdk/IsolatedFileSystem.js

Issue 471433004: DevTools: Split out the "workspace" and "bindings" modules from "sdk" (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Remove marker interfaces and WI.SourceMapping Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(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 * @constructor
33 * @param {!WebInspector.IsolatedFileSystemManager} manager
34 * @param {string} path
35 * @param {string} name
36 * @param {string} rootURL
37 */
38 WebInspector.IsolatedFileSystem = function(manager, path, name, rootURL)
39 {
40 this._manager = manager;
41 this._path = path;
42 this._name = name;
43 this._rootURL = rootURL;
44 }
45
46 /**
47 * @param {!FileError} error
48 * @return {string}
49 */
50 WebInspector.IsolatedFileSystem.errorMessage = function(error)
51 {
52 return WebInspector.UIString("File system error: %s", error.message);
53 }
54
55 /**
56 * @param {string} fileSystemPath
57 * @return {string}
58 */
59 WebInspector.IsolatedFileSystem.normalizePath = function(fileSystemPath)
60 {
61 if (WebInspector.isWin())
62 return fileSystemPath.replace(/\\/g, "/");
63 return fileSystemPath;
64 }
65
66 WebInspector.IsolatedFileSystem.prototype = {
67 /**
68 * @return {string}
69 */
70 path: function()
71 {
72 return this._path;
73 },
74
75 /**
76 * @return {string}
77 */
78 normalizedPath: function()
79 {
80 if (this._normalizedPath)
81 return this._normalizedPath;
82 this._normalizedPath = WebInspector.IsolatedFileSystem.normalizePath(thi s._path);
83 return this._normalizedPath;
84 },
85
86 /**
87 * @return {string}
88 */
89 name: function()
90 {
91 return this._name;
92 },
93
94 /**
95 * @return {string}
96 */
97 rootURL: function()
98 {
99 return this._rootURL;
100 },
101
102 /**
103 * @param {function(?DOMFileSystem)} callback
104 */
105 _requestFileSystem: function(callback)
106 {
107 this._manager.requestDOMFileSystem(this._path, callback);
108 },
109
110 /**
111 * @param {string} path
112 * @param {function(string)} fileCallback
113 * @param {function()=} finishedCallback
114 */
115 requestFilesRecursive: function(path, fileCallback, finishedCallback)
116 {
117 var domFileSystem;
118 var pendingRequests = 0;
119 this._requestFileSystem(fileSystemLoaded.bind(this));
120 /**
121 * @param {?DOMFileSystem} fs
122 * @this {WebInspector.IsolatedFileSystem}
123 */
124 function fileSystemLoaded(fs)
125 {
126 domFileSystem = /** @type {!DOMFileSystem} */ (fs);
127 console.assert(domFileSystem);
128 ++pendingRequests;
129 this._requestEntries(domFileSystem, path, innerCallback.bind(this));
130 }
131
132 /**
133 * @param {!Array.<!FileEntry>} entries
134 * @this {WebInspector.IsolatedFileSystem}
135 */
136 function innerCallback(entries)
137 {
138 for (var i = 0; i < entries.length; ++i) {
139 var entry = entries[i];
140 if (!entry.isDirectory) {
141 if (this._manager.mapping().isFileExcluded(this._path, entry .fullPath))
142 continue;
143 fileCallback(entry.fullPath.substr(1));
144 }
145 else {
146 if (this._manager.mapping().isFileExcluded(this._path, entry .fullPath + "/"))
147 continue;
148 ++pendingRequests;
149 this._requestEntries(domFileSystem, entry.fullPath, innerCal lback.bind(this));
150 }
151 }
152 if (finishedCallback && (--pendingRequests === 0))
153 finishedCallback();
154 }
155 },
156
157 /**
158 * @param {string} path
159 * @param {?string} name
160 * @param {function(?string)} callback
161 */
162 createFile: function(path, name, callback)
163 {
164 this._requestFileSystem(fileSystemLoaded.bind(this));
165 var newFileIndex = 1;
166 if (!name)
167 name = "NewFile";
168 var nameCandidate;
169
170 /**
171 * @param {?DOMFileSystem} fs
172 * @this {WebInspector.IsolatedFileSystem}
173 */
174 function fileSystemLoaded(fs)
175 {
176 var domFileSystem = /** @type {!DOMFileSystem} */ (fs);
177 console.assert(domFileSystem);
178 domFileSystem.root.getDirectory(path, null, dirEntryLoaded.bind(this ), errorHandler.bind(this));
179 }
180
181 /**
182 * @param {!DirectoryEntry} dirEntry
183 * @this {WebInspector.IsolatedFileSystem}
184 */
185 function dirEntryLoaded(dirEntry)
186 {
187 var nameCandidate = name;
188 if (newFileIndex > 1)
189 nameCandidate += newFileIndex;
190 ++newFileIndex;
191 dirEntry.getFile(nameCandidate, { create: true, exclusive: true }, f ileCreated, fileCreationError.bind(this));
192
193 function fileCreated(entry)
194 {
195 callback(entry.fullPath.substr(1));
196 }
197
198 /**
199 * @this {WebInspector.IsolatedFileSystem}
200 */
201 function fileCreationError(error)
202 {
203 if (error.code === FileError.INVALID_MODIFICATION_ERR) {
204 dirEntryLoaded.call(this, dirEntry);
205 return;
206 }
207
208 var errorMessage = WebInspector.IsolatedFileSystem.errorMessage( error);
209 console.error(errorMessage + " when testing if file exists '" + (this._path + "/" + path + "/" + nameCandidate) + "'");
210 callback(null);
211 }
212 }
213
214 /**
215 * @this {WebInspector.IsolatedFileSystem}
216 */
217 function errorHandler(error)
218 {
219 var errorMessage = WebInspector.IsolatedFileSystem.errorMessage(erro r);
220 var filePath = this._path + "/" + path;
221 if (nameCandidate)
222 filePath += "/" + nameCandidate;
223 console.error(errorMessage + " when getting content for file '" + (f ilePath) + "'");
224 callback(null);
225 }
226 },
227
228 /**
229 * @param {string} path
230 */
231 deleteFile: function(path)
232 {
233 this._requestFileSystem(fileSystemLoaded.bind(this));
234
235 /**
236 * @param {?DOMFileSystem} fs
237 * @this {WebInspector.IsolatedFileSystem}
238 */
239 function fileSystemLoaded(fs)
240 {
241 var domFileSystem = /** @type {!DOMFileSystem} */ (fs);
242 console.assert(domFileSystem);
243 domFileSystem.root.getFile(path, null, fileEntryLoaded.bind(this), e rrorHandler.bind(this));
244 }
245
246 /**
247 * @param {!FileEntry} fileEntry
248 * @this {WebInspector.IsolatedFileSystem}
249 */
250 function fileEntryLoaded(fileEntry)
251 {
252 fileEntry.remove(fileEntryRemoved, errorHandler.bind(this));
253 }
254
255 function fileEntryRemoved()
256 {
257 }
258
259 /**
260 * @param {!FileError} error
261 * @this {WebInspector.IsolatedFileSystem}
262 */
263 function errorHandler(error)
264 {
265 var errorMessage = WebInspector.IsolatedFileSystem.errorMessage(erro r);
266 console.error(errorMessage + " when deleting file '" + (this._path + "/" + path) + "'");
267 }
268 },
269
270 /**
271 * @param {string} path
272 * @param {function(?Date, ?number)} callback
273 */
274 requestMetadata: function(path, callback)
275 {
276 this._requestFileSystem(fileSystemLoaded);
277
278 /**
279 * @param {?DOMFileSystem} fs
280 */
281 function fileSystemLoaded(fs)
282 {
283 var domFileSystem = /** @type {!DOMFileSystem} */ (fs);
284 console.assert(domFileSystem);
285 domFileSystem.root.getFile(path, null, fileEntryLoaded, errorHandler );
286 }
287
288 /**
289 * @param {!FileEntry} entry
290 */
291 function fileEntryLoaded(entry)
292 {
293 entry.getMetadata(successHandler, errorHandler);
294 }
295
296 /**
297 * @param {!Metadata} metadata
298 */
299 function successHandler(metadata)
300 {
301 callback(metadata.modificationTime, metadata.size);
302 }
303
304 /**
305 * @param {!FileError} error
306 */
307 function errorHandler(error)
308 {
309 callback(null, null);
310 }
311 },
312
313 /**
314 * @param {string} path
315 * @param {function(?string)} callback
316 */
317 requestFileContent: function(path, callback)
318 {
319 this._requestFileSystem(fileSystemLoaded.bind(this));
320
321 /**
322 * @param {?DOMFileSystem} fs
323 * @this {WebInspector.IsolatedFileSystem}
324 */
325 function fileSystemLoaded(fs)
326 {
327 var domFileSystem = /** @type {!DOMFileSystem} */ (fs);
328 console.assert(domFileSystem);
329 domFileSystem.root.getFile(path, null, fileEntryLoaded.bind(this), e rrorHandler.bind(this));
330 }
331
332 /**
333 * @param {!FileEntry} entry
334 * @this {WebInspector.IsolatedFileSystem}
335 */
336 function fileEntryLoaded(entry)
337 {
338 entry.file(fileLoaded, errorHandler.bind(this));
339 }
340
341 /**
342 * @param {!Blob} file
343 */
344 function fileLoaded(file)
345 {
346 var reader = new FileReader();
347 reader.onloadend = readerLoadEnd;
348 reader.readAsText(file);
349 }
350
351 /**
352 * @this {!FileReader}
353 */
354 function readerLoadEnd()
355 {
356 callback(/** @type {string} */ (this.result));
357 }
358
359 /**
360 * @this {WebInspector.IsolatedFileSystem}
361 */
362 function errorHandler(error)
363 {
364 if (error.code === FileError.NOT_FOUND_ERR) {
365 callback(null);
366 return;
367 }
368
369 var errorMessage = WebInspector.IsolatedFileSystem.errorMessage(erro r);
370 console.error(errorMessage + " when getting content for file '" + (t his._path + "/" + path) + "'");
371 callback(null);
372 }
373 },
374
375 /**
376 * @param {string} path
377 * @param {string} content
378 * @param {function()} callback
379 */
380 setFileContent: function(path, content, callback)
381 {
382 this._requestFileSystem(fileSystemLoaded.bind(this));
383 WebInspector.userMetrics.FileSavedInWorkspace.record();
384
385 /**
386 * @param {?DOMFileSystem} fs
387 * @this {WebInspector.IsolatedFileSystem}
388 */
389 function fileSystemLoaded(fs)
390 {
391 var domFileSystem = /** @type {!DOMFileSystem} */ (fs);
392 console.assert(domFileSystem);
393 domFileSystem.root.getFile(path, { create: true }, fileEntryLoaded.b ind(this), errorHandler.bind(this));
394 }
395
396 /**
397 * @param {!FileEntry} entry
398 * @this {WebInspector.IsolatedFileSystem}
399 */
400 function fileEntryLoaded(entry)
401 {
402 entry.createWriter(fileWriterCreated.bind(this), errorHandler.bind(t his));
403 }
404
405 /**
406 * @param {!FileWriter} fileWriter
407 * @this {WebInspector.IsolatedFileSystem}
408 */
409 function fileWriterCreated(fileWriter)
410 {
411 fileWriter.onerror = errorHandler.bind(this);
412 fileWriter.onwriteend = fileTruncated;
413 fileWriter.truncate(0);
414
415 function fileTruncated()
416 {
417 fileWriter.onwriteend = writerEnd;
418 var blob = new Blob([content], { type: "text/plain" });
419 fileWriter.write(blob);
420 }
421 }
422
423 function writerEnd()
424 {
425 callback();
426 }
427
428 /**
429 * @this {WebInspector.IsolatedFileSystem}
430 */
431 function errorHandler(error)
432 {
433 var errorMessage = WebInspector.IsolatedFileSystem.errorMessage(erro r);
434 console.error(errorMessage + " when setting content for file '" + (t his._path + "/" + path) + "'");
435 callback();
436 }
437 },
438
439 /**
440 * @param {string} path
441 * @param {string} newName
442 * @param {function(boolean, string=)} callback
443 */
444 renameFile: function(path, newName, callback)
445 {
446 newName = newName ? newName.trim() : newName;
447 if (!newName || newName.indexOf("/") !== -1) {
448 callback(false);
449 return;
450 }
451 var fileEntry;
452 var dirEntry;
453 var newFileEntry;
454 this._requestFileSystem(fileSystemLoaded.bind(this));
455
456 /**
457 * @param {?DOMFileSystem} fs
458 * @this {WebInspector.IsolatedFileSystem}
459 */
460 function fileSystemLoaded(fs)
461 {
462 var domFileSystem = /** @type {!DOMFileSystem} */ (fs);
463 console.assert(domFileSystem);
464 domFileSystem.root.getFile(path, null, fileEntryLoaded.bind(this), e rrorHandler.bind(this));
465 }
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.code !== FileError.NOT_FOUND_ERR) {
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 {!DOMFileSystem} domFileSystem
567 * @param {string} path
568 * @param {function(!Array.<!FileEntry>)} callback
569 */
570 _requestEntries: function(domFileSystem, path, callback)
571 {
572 domFileSystem.root.getDirectory(path, null, innerCallback.bind(this), er rorHandler);
573
574 /**
575 * @param {!DirectoryEntry} dirEntry
576 * @this {WebInspector.IsolatedFileSystem}
577 */
578 function innerCallback(dirEntry)
579 {
580 this._readDirectory(dirEntry, callback)
581 }
582
583 function errorHandler(error)
584 {
585 var errorMessage = WebInspector.IsolatedFileSystem.errorMessage(erro r);
586 console.error(errorMessage + " when requesting entry '" + path + "'" );
587 callback([]);
588 }
589 }
590 }
OLDNEW
« no previous file with comments | « Source/devtools/front_end/sdk/FileUtils.js ('k') | Source/devtools/front_end/sdk/IsolatedFileSystemManager.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698