| 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 |