OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 'use strict'; | 5 'use strict'; |
6 | 6 |
7 /** | 7 /** |
8 * Namespace for utility functions. | 8 * Namespace for utility functions. |
9 */ | 9 */ |
10 var util = {}; | 10 var util = {}; |
(...skipping 265 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
276 function(err) { | 276 function(err) { |
277 errorCallback(err); | 277 errorCallback(err); |
278 getNextFile(); | 278 getNextFile(); |
279 }); | 279 }); |
280 }; | 280 }; |
281 | 281 |
282 getNextFile(); | 282 getNextFile(); |
283 }; | 283 }; |
284 | 284 |
285 /** | 285 /** |
286 * Resolve a path to either a DirectoryEntry or a FileEntry, regardless of | |
287 * whether the path is a directory or file. | |
288 * | |
289 * @param {DirectoryEntry} root The root of the filesystem to search. | |
290 * @param {string} path The path to be resolved. | |
291 * @param {function(Entry)} resultCallback Called back when a path is | |
292 * successfully resolved. Entry will be either a DirectoryEntry or | |
293 * a FileEntry. | |
294 * @param {function(FileError)} errorCallback Called back if an unexpected | |
295 * error occurs while resolving the path. | |
296 */ | |
297 util.resolvePath = function(root, path, resultCallback, errorCallback) { | |
298 if (path == '' || path == '/') { | |
299 resultCallback(root); | |
300 return; | |
301 } | |
302 | |
303 root.getFile( | |
304 path, {create: false}, | |
305 resultCallback, | |
306 function(err) { | |
307 if (err.name == util.FileError.TYPE_MISMATCH_ERR) { | |
308 // Bah. It's a directory, ask again. | |
309 root.getDirectory( | |
310 path, {create: false}, | |
311 resultCallback, | |
312 errorCallback); | |
313 } else { | |
314 errorCallback(err); | |
315 } | |
316 }); | |
317 }; | |
318 | |
319 /** | |
320 * Renames the entry to newName. | 286 * Renames the entry to newName. |
321 * @param {Entry} entry The entry to be renamed. | 287 * @param {Entry} entry The entry to be renamed. |
322 * @param {string} newName The new name. | 288 * @param {string} newName The new name. |
323 * @param {function(Entry)} successCallback Callback invoked when the rename | 289 * @param {function(Entry)} successCallback Callback invoked when the rename |
324 * is successfully done. | 290 * is successfully done. |
325 * @param {function(FileError)} errorCallback Callback invoked when an error | 291 * @param {function(FileError)} errorCallback Callback invoked when an error |
326 * is found. | 292 * is found. |
327 */ | 293 */ |
328 util.rename = function(entry, newName, successCallback, errorCallback) { | 294 util.rename = function(entry, newName, successCallback, errorCallback) { |
329 entry.getParent(function(parent) { | 295 entry.getParent(function(parent) { |
(...skipping 29 matching lines...) Expand all Loading... |
359 * @param {function(FileError)} onError The error callback. | 325 * @param {function(FileError)} onError The error callback. |
360 */ | 326 */ |
361 util.removeFileOrDirectory = function(entry, onSuccess, onError) { | 327 util.removeFileOrDirectory = function(entry, onSuccess, onError) { |
362 if (entry.isDirectory) | 328 if (entry.isDirectory) |
363 entry.removeRecursively(onSuccess, onError); | 329 entry.removeRecursively(onSuccess, onError); |
364 else | 330 else |
365 entry.remove(onSuccess, onError); | 331 entry.remove(onSuccess, onError); |
366 }; | 332 }; |
367 | 333 |
368 /** | 334 /** |
369 * Checks if an entry exists at |relativePath| in |dirEntry|. | |
370 * If exists, tries to deduplicate the path by inserting parenthesized number, | |
371 * such as " (1)", before the extension. If it still exists, tries the | |
372 * deduplication again by increasing the number up to 10 times. | |
373 * For example, suppose "file.txt" is given, "file.txt", "file (1).txt", | |
374 * "file (2).txt", ..., "file (9).txt" will be tried. | |
375 * | |
376 * @param {DirectoryEntry} dirEntry The target directory entry. | |
377 * @param {string} relativePath The path to be deduplicated. | |
378 * @param {function(string)} onSuccess Called with the deduplicated path on | |
379 * success. | |
380 * @param {function(FileError)} onError Called on error. | |
381 */ | |
382 util.deduplicatePath = function(dirEntry, relativePath, onSuccess, onError) { | |
383 // The trial is up to 10. | |
384 var MAX_RETRY = 10; | |
385 | |
386 // Crack the path into three part. The parenthesized number (if exists) will | |
387 // be replaced by incremented number for retry. For example, suppose | |
388 // |relativePath| is "file (10).txt", the second check path will be | |
389 // "file (11).txt". | |
390 var match = /^(.*?)(?: \((\d+)\))?(\.[^.]*?)?$/.exec(relativePath); | |
391 var prefix = match[1]; | |
392 var copyNumber = match[2] ? parseInt(match[2], 10) : 0; | |
393 var ext = match[3] ? match[3] : ''; | |
394 | |
395 // The path currently checking the existence. | |
396 var trialPath = relativePath; | |
397 | |
398 var onNotResolved = function(err) { | |
399 // We expect to be unable to resolve the target file, since we're going | |
400 // to create it during the copy. However, if the resolve fails with | |
401 // anything other than NOT_FOUND, that's trouble. | |
402 if (err.name != util.FileError.NOT_FOUND_ERR) { | |
403 onError(err); | |
404 return; | |
405 } | |
406 | |
407 // Found a path that doesn't exist. | |
408 onSuccess(trialPath); | |
409 }; | |
410 | |
411 var numRetry = MAX_RETRY; | |
412 var onResolved = function(entry) { | |
413 if (--numRetry == 0) { | |
414 // Hit the limit of the number of retrial. | |
415 // Note that we cannot create FileError object directly, so here we use | |
416 // Object.create instead. | |
417 onError(util.createDOMError(util.FileError.PATH_EXISTS_ERR)); | |
418 return; | |
419 } | |
420 | |
421 ++copyNumber; | |
422 trialPath = prefix + ' (' + copyNumber + ')' + ext; | |
423 util.resolvePath(dirEntry, trialPath, onResolved, onNotResolved); | |
424 }; | |
425 | |
426 // Check to see if the target exists. | |
427 util.resolvePath(dirEntry, trialPath, onResolved, onNotResolved); | |
428 }; | |
429 | |
430 /** | |
431 * Convert a number of bytes into a human friendly format, using the correct | 335 * Convert a number of bytes into a human friendly format, using the correct |
432 * number separators. | 336 * number separators. |
433 * | 337 * |
434 * @param {number} bytes The number of bytes. | 338 * @param {number} bytes The number of bytes. |
435 * @return {string} Localized string. | 339 * @return {string} Localized string. |
436 */ | 340 */ |
437 util.bytesToString = function(bytes) { | 341 util.bytesToString = function(bytes) { |
438 // Translation identifiers for size units. | 342 // Translation identifiers for size units. |
439 var UNITS = ['SIZE_BYTES', | 343 var UNITS = ['SIZE_BYTES', |
440 'SIZE_KB', | 344 'SIZE_KB', |
(...skipping 979 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1420 parentEntry.toURL(), | 1324 parentEntry.toURL(), |
1421 name, | 1325 name, |
1422 function(valid) { | 1326 function(valid) { |
1423 if (valid) | 1327 if (valid) |
1424 fulfill(); | 1328 fulfill(); |
1425 else | 1329 else |
1426 reject(str('ERROR_LONG_NAME')); | 1330 reject(str('ERROR_LONG_NAME')); |
1427 }); | 1331 }); |
1428 }); | 1332 }); |
1429 }; | 1333 }; |
OLD | NEW |