OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 // Setting the src of an img to an empty string can crash the browser, so we | 5 // Setting the src of an img to an empty string can crash the browser, so we |
6 // use an empty 1x1 gif instead. | 6 // use an empty 1x1 gif instead. |
7 const EMPTY_IMAGE_URI = 'data:image/gif;base64,' | 7 const EMPTY_IMAGE_URI = 'data:image/gif;base64,' |
8 + 'R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw%3D%3D'; | 8 + 'R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw%3D%3D'; |
9 | 9 |
10 var g_slideshow_data = null; | 10 var g_slideshow_data = null; |
(...skipping 397 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
408 } | 408 } |
409 | 409 |
410 delete entry[observerList]; | 410 delete entry[observerList]; |
411 }; | 411 }; |
412 | 412 |
413 entry[methodName](function(rv) { onComplete(true, rv) }, | 413 entry[methodName](function(rv) { onComplete(true, rv) }, |
414 function(rv) { onComplete(false, rv) }); | 414 function(rv) { onComplete(false, rv) }); |
415 } | 415 } |
416 | 416 |
417 /** | 417 /** |
| 418 * Invoke callback in sync/async manner. |
| 419 * @param {function(*)?} callback The callback. If null, nothing is called. |
| 420 * @param {boolean} sync True iff the callback should be called synchronously. |
| 421 * @param {*} callback_args... The rest are callback arguments. |
| 422 */ |
| 423 function invokeCallback(callback, sync, callback_args) { |
| 424 if (!callback) |
| 425 return; |
| 426 var args = Array.prototype.slice.call(arguments, 2); |
| 427 if (sync) { |
| 428 callback.apply(null, args); |
| 429 } else { |
| 430 setTimeout(function() { callback.apply(null, args); }, 0); |
| 431 } |
| 432 } |
| 433 |
| 434 /** |
418 * Get the size of a file, caching the result. | 435 * Get the size of a file, caching the result. |
419 * | 436 * |
420 * When this method completes, the fileEntry object will get a | 437 * When this method completes, the fileEntry object will get a |
421 * 'cachedSize_' property (if it doesn't already have one) containing the | 438 * 'cachedSize_' property (if it doesn't already have one) containing the |
422 * size of the file in bytes. | 439 * size of the file in bytes. |
423 * | 440 * |
424 * @param {Entry} entry An HTML5 Entry object. | 441 * @param {Entry} entry An HTML5 Entry object. |
425 * @param {function(Entry)} successCallback The function to invoke once the | 442 * @param {function(Entry)} successCallback The function to invoke once the |
426 * file size is known. | 443 * file size is known. |
| 444 * @param {function=} opt_errorCallback Error callback. |
| 445 * @param {boolean=} opt_sync True, if callback should be called sync instead |
| 446 * of async. |
427 */ | 447 */ |
428 function cacheEntrySize(entry, successCallback, opt_errorCallback) { | 448 function cacheEntrySize(entry, successCallback, opt_errorCallback, opt_sync) { |
429 if (entry.isDirectory) { | 449 if (entry.isDirectory) { |
430 // No size for a directory, -1 ensures it's sorted before 0 length files. | 450 // No size for a directory, -1 ensures it's sorted before 0 length files. |
431 entry.cachedSize_ = -1; | 451 entry.cachedSize_ = -1; |
432 } | 452 } |
433 | 453 |
434 if ('cachedSize_' in entry) { | 454 if ('cachedSize_' in entry) { |
435 if (successCallback) { | 455 invokeCallback(successCallback, !!opt_sync, entry); |
436 // Callback via a setTimeout so the sync/async semantics don't change | |
437 // based on whether or not the value is cached. | |
438 setTimeout(function() { successCallback(entry) }, 0); | |
439 } | |
440 return; | 456 return; |
441 } | 457 } |
442 | 458 |
443 batchAsyncCall(entry, 'file', function(file) { | 459 batchAsyncCall(entry, 'file', function(file) { |
444 entry.cachedSize_ = file.size; | 460 entry.cachedSize_ = file.size; |
445 if (successCallback) | 461 if (successCallback) |
446 successCallback(entry); | 462 successCallback(entry); |
447 }, opt_errorCallback); | 463 }, opt_errorCallback); |
448 } | 464 } |
449 | 465 |
450 /** | 466 /** |
451 * Get the mtime of a file, caching the result. | 467 * Get the mtime of a file, caching the result. |
452 * | 468 * |
453 * When this method completes, the fileEntry object will get a | 469 * When this method completes, the fileEntry object will get a |
454 * 'cachedMtime_' property (if it doesn't already have one) containing the | 470 * 'cachedMtime_' property (if it doesn't already have one) containing the |
455 * last modified time of the file as a Date object. | 471 * last modified time of the file as a Date object. |
456 * | 472 * |
457 * @param {Entry} entry An HTML5 Entry object. | 473 * @param {Entry} entry An HTML5 Entry object. |
458 * @param {function(Entry)} successCallback The function to invoke once the | 474 * @param {function(Entry)} successCallback The function to invoke once the |
459 * mtime is known. | 475 * mtime is known. |
| 476 * @param {function=} opt_errorCallback Error callback. |
| 477 * @param {boolean=} opt_sync True, if callback should be called sync instead |
| 478 * of async. |
460 */ | 479 */ |
461 function cacheEntryDate(entry, successCallback, opt_errorCallback) { | 480 function cacheEntryDate(entry, successCallback, opt_errorCallback, opt_sync) { |
462 if ('cachedMtime_' in entry) { | 481 if ('cachedMtime_' in entry) { |
463 if (successCallback) { | 482 invokeCallback(successCallback, !!opt_sync, entry); |
464 // Callback via a setTimeout so the sync/async semantics don't change | |
465 // based on whether or not the value is cached. | |
466 setTimeout(function() { successCallback(entry) }, 0); | |
467 } | |
468 return; | 483 return; |
469 } | 484 } |
470 | 485 |
471 if (entry.isFile) { | 486 if (entry.isFile) { |
472 batchAsyncCall(entry, 'file', function(file) { | 487 batchAsyncCall(entry, 'file', function(file) { |
473 entry.cachedMtime_ = file.lastModifiedDate; | 488 entry.cachedMtime_ = file.lastModifiedDate; |
474 if (successCallback) | 489 if (successCallback) |
475 successCallback(entry); | 490 successCallback(entry); |
476 }); | 491 }); |
477 } else { | 492 } else { |
(...skipping 277 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
755 /** | 770 /** |
756 * Get the file type of the entry, caching the result. | 771 * Get the file type of the entry, caching the result. |
757 * | 772 * |
758 * When this method completes, the entry object will get a | 773 * When this method completes, the entry object will get a |
759 * 'cachedIconType_' property (if it doesn't already have one) containing the | 774 * 'cachedIconType_' property (if it doesn't already have one) containing the |
760 * icon type of the file as a string. | 775 * icon type of the file as a string. |
761 * | 776 * |
762 * @param {Entry} entry An HTML5 Entry object. | 777 * @param {Entry} entry An HTML5 Entry object. |
763 * @param {function(Entry)} successCallback The function to invoke once the | 778 * @param {function(Entry)} successCallback The function to invoke once the |
764 * file size is known. | 779 * file size is known. |
| 780 * @param {boolean=} opt_sync If true, we are safe to do synchronous callback. |
765 */ | 781 */ |
766 FileManager.prototype.cacheEntryFileType = function(entry, successCallback) { | 782 FileManager.prototype.cacheEntryFileType = function( |
| 783 entry, successCallback, opt_sync) { |
767 this.getFileType(entry); | 784 this.getFileType(entry); |
768 | 785 invokeCallback(successCallback, !!opt_sync, entry); |
769 if (successCallback) | |
770 setTimeout(function() { successCallback(entry) }, 0); | |
771 }; | 786 }; |
772 | 787 |
773 /** | 788 /** |
774 * Compare by mtime first, then by name. | 789 * Compare by mtime first, then by name. |
775 */ | 790 */ |
776 FileManager.prototype.compareMtime_ = function(a, b) { | 791 FileManager.prototype.compareMtime_ = function(a, b) { |
777 if (a.cachedMtime_ > b.cachedMtime_) | 792 if (a.cachedMtime_ > b.cachedMtime_) |
778 return 1; | 793 return 1; |
779 | 794 |
780 if (a.cachedMtime_ < b.cachedMtime_) | 795 if (a.cachedMtime_ < b.cachedMtime_) |
(...skipping 764 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1545 */ | 1560 */ |
1546 FileManager.prototype.renderIconType_ = function(entry, columnId, table) { | 1561 FileManager.prototype.renderIconType_ = function(entry, columnId, table) { |
1547 var div = this.document_.createElement('div'); | 1562 var div = this.document_.createElement('div'); |
1548 div.className = 'detail-icon-container'; | 1563 div.className = 'detail-icon-container'; |
1549 | 1564 |
1550 if (this.showCheckboxes_) | 1565 if (this.showCheckboxes_) |
1551 div.appendChild(this.renderCheckbox_(entry)); | 1566 div.appendChild(this.renderCheckbox_(entry)); |
1552 | 1567 |
1553 var icon = this.document_.createElement('div'); | 1568 var icon = this.document_.createElement('div'); |
1554 icon.className = 'detail-icon'; | 1569 icon.className = 'detail-icon'; |
1555 this.cacheEntryIconType(entry); | 1570 this.getIconType(entry); |
1556 icon.setAttribute('iconType', entry.cachedIconType_); | 1571 icon.setAttribute('iconType', entry.cachedIconType_); |
1557 div.appendChild(icon); | 1572 div.appendChild(icon); |
1558 | 1573 |
1559 return div; | 1574 return div; |
1560 }; | 1575 }; |
1561 | 1576 |
1562 FileManager.prototype.getLabelForRootPath_ = function(path) { | 1577 FileManager.prototype.getLabelForRootPath_ = function(path) { |
1563 // This hack lets us localize the top level directories. | 1578 // This hack lets us localize the top level directories. |
1564 if (path == 'Downloads') | 1579 if (path == 'Downloads') |
1565 return str('DOWNLOADS_DIRECTORY_LABEL'); | 1580 return str('DOWNLOADS_DIRECTORY_LABEL'); |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1606 var div = this.document_.createElement('div'); | 1621 var div = this.document_.createElement('div'); |
1607 div.className = 'detail-size'; | 1622 div.className = 'detail-size'; |
1608 | 1623 |
1609 div.textContent = '...'; | 1624 div.textContent = '...'; |
1610 cacheEntrySize(entry, function(entry) { | 1625 cacheEntrySize(entry, function(entry) { |
1611 if (entry.cachedSize_ == -1) { | 1626 if (entry.cachedSize_ == -1) { |
1612 div.textContent = ''; | 1627 div.textContent = ''; |
1613 } else { | 1628 } else { |
1614 div.textContent = util.bytesToSi(entry.cachedSize_); | 1629 div.textContent = util.bytesToSi(entry.cachedSize_); |
1615 } | 1630 } |
1616 }); | 1631 }, null, true); |
1617 | 1632 |
1618 return div; | 1633 return div; |
1619 }; | 1634 }; |
1620 | 1635 |
1621 /** | 1636 /** |
1622 * Render the Type column of the detail table. | 1637 * Render the Type column of the detail table. |
1623 * | 1638 * |
1624 * @param {Entry} entry The Entry object to render. | 1639 * @param {Entry} entry The Entry object to render. |
1625 * @param {string} columnId The id of the column to be rendered. | 1640 * @param {string} columnId The id of the column to be rendered. |
1626 * @param {cr.ui.Table} table The table doing the rendering. | 1641 * @param {cr.ui.Table} table The table doing the rendering. |
1627 */ | 1642 */ |
1628 FileManager.prototype.renderType_ = function(entry, columnId, table) { | 1643 FileManager.prototype.renderType_ = function(entry, columnId, table) { |
1629 var div = this.document_.createElement('div'); | 1644 var div = this.document_.createElement('div'); |
1630 div.className = 'detail-type'; | 1645 div.className = 'detail-type'; |
1631 | 1646 |
1632 div.textContent = '...'; | |
1633 this.cacheEntryFileType(entry, function(entry) { | 1647 this.cacheEntryFileType(entry, function(entry) { |
1634 var info = entry.cachedFileType_; | 1648 var info = entry.cachedFileType_; |
1635 if (info.name) { | 1649 if (info.name) { |
1636 if (info.subtype) | 1650 if (info.subtype) |
1637 div.textContent = strf(info.name, info.subtype); | 1651 div.textContent = strf(info.name, info.subtype); |
1638 else | 1652 else |
1639 div.textContent = str(info.name); | 1653 div.textContent = str(info.name); |
1640 } else | 1654 } else |
1641 div.textContent = ''; | 1655 div.textContent = ''; |
1642 }); | 1656 }, true); |
1643 | 1657 |
1644 return div; | 1658 return div; |
1645 }; | 1659 }; |
1646 | 1660 |
1647 /** | 1661 /** |
1648 * Render the Date column of the detail table. | 1662 * Render the Date column of the detail table. |
1649 * | 1663 * |
1650 * @param {Entry} entry The Entry object to render. | 1664 * @param {Entry} entry The Entry object to render. |
1651 * @param {string} columnId The id of the column to be rendered. | 1665 * @param {string} columnId The id of the column to be rendered. |
1652 * @param {cr.ui.Table} table The table doing the rendering. | 1666 * @param {cr.ui.Table} table The table doing the rendering. |
1653 */ | 1667 */ |
1654 FileManager.prototype.renderDate_ = function(entry, columnId, table) { | 1668 FileManager.prototype.renderDate_ = function(entry, columnId, table) { |
1655 var div = this.document_.createElement('div'); | 1669 var div = this.document_.createElement('div'); |
1656 div.className = 'detail-date'; | 1670 div.className = 'detail-date'; |
1657 | 1671 |
1658 div.textContent = '...'; | 1672 div.textContent = '...'; |
1659 | 1673 |
1660 var self = this; | 1674 var self = this; |
1661 cacheEntryDate(entry, function(entry) { | 1675 cacheEntryDate(entry, function(entry) { |
1662 if (isSystemDirEntry(self.currentDirEntry_) && | 1676 if (isSystemDirEntry(self.currentDirEntry_) && |
1663 entry.cachedMtime_.getTime() == 0) { | 1677 entry.cachedMtime_.getTime() == 0) { |
1664 // Mount points for FAT volumes have this time associated with them. | 1678 // Mount points for FAT volumes have this time associated with them. |
1665 // We'd rather display nothing than this bogus date. | 1679 // We'd rather display nothing than this bogus date. |
1666 div.textContent = ''; | 1680 div.textContent = ''; |
1667 } else { | 1681 } else { |
1668 div.textContent = self.shortDateFormatter_.format(entry.cachedMtime_); | 1682 div.textContent = self.shortDateFormatter_.format(entry.cachedMtime_); |
1669 } | 1683 } |
1670 }); | 1684 }, null, true); |
1671 | 1685 |
1672 return div; | 1686 return div; |
1673 }; | 1687 }; |
1674 | 1688 |
1675 /** | 1689 /** |
1676 * Compute summary information about the current selection. | 1690 * Compute summary information about the current selection. |
1677 * | 1691 * |
1678 * This method dispatches the 'selection-summarized' event when it completes. | 1692 * This method dispatches the 'selection-summarized' event when it completes. |
1679 * Depending on how many of the selected files already have known sizes, the | 1693 * Depending on how many of the selected files already have known sizes, the |
1680 * dispatch may happen immediately, or after a number of async calls complete. | 1694 * dispatch may happen immediately, or after a number of async calls complete. |
(...skipping 1901 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3582 | 3596 |
3583 if (msg) { | 3597 if (msg) { |
3584 console.log('no no no'); | 3598 console.log('no no no'); |
3585 this.alert.show(msg, onAccept); | 3599 this.alert.show(msg, onAccept); |
3586 return false; | 3600 return false; |
3587 } | 3601 } |
3588 | 3602 |
3589 return true; | 3603 return true; |
3590 }; | 3604 }; |
3591 })(); | 3605 })(); |
OLD | NEW |