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

Side by Side Diff: chrome/browser/resources/file_manager/js/file_manager.js

Issue 8477027: [filebrowser] Improve scrolling by converting some async calls to sync. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 9 years, 1 month 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
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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 })();
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698