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

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

Issue 9855024: Postpone connecting to GData even more, provide progress indication. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Simplified, addressed comments. Created 8 years, 9 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
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 // 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 7
8 /** 8 /**
9 * FileManager constructor. 9 * FileManager constructor.
10 * 10 *
(...skipping 536 matching lines...) Expand 10 before | Expand all | Expand 10 after
547 chrome.fileBrowserPrivate.onMountCompleted.addListener( 547 chrome.fileBrowserPrivate.onMountCompleted.addListener(
548 this.onMountCompleted_.bind(this)); 548 this.onMountCompleted_.bind(this));
549 549
550 chrome.fileBrowserPrivate.onFileChanged.addListener( 550 chrome.fileBrowserPrivate.onFileChanged.addListener(
551 this.onFileChanged_.bind(this)); 551 this.onFileChanged_.bind(this));
552 552
553 // The list of callbacks to be invoked during the directory rescan after 553 // The list of callbacks to be invoked during the directory rescan after
554 // all paste tasks are complete. 554 // all paste tasks are complete.
555 this.pasteSuccessCallbacks_ = []; 555 this.pasteSuccessCallbacks_ = [];
556 556
557 this.setupCurrentDirectory_(); 557 var path = this.getPathFromUrlOrParams_();
558 if (path &&
559 DirectoryModel.getRootType(path) == DirectoryModel.RootType.GDATA) {
560 // We are opening on a GData path. Mount GData and show
561 // "Loading Google Docs" message until the directory content loads.
562 this.dialogContainer_.setAttribute('unmounted', true);
563 this.initGData_(true /* dirChanged */);
564 // This is a one-time handler (will be nulled out on the first call).
565 this.setupCurrentDirectoryPostponed_ = function(event) {
566 this.directoryModel_.removeEventListener('directory-changed',
567 this.setupCurrentDirectoryPostponed_);
568 this.setupCurrentDirectoryPostponed_ = null;
569 if (event) // If called as an event handler just exit silently.
570 return;
571 this.setupCurrentDirectory_(false /* blankWhileOpeningAFile */);
572 }.bind(this);
573 this.directoryModel_.addEventListener('directory-changed',
574 this.setupCurrentDirectoryPostponed_);
575 } else {
576 this.setupCurrentDirectory_(true /* blankWhileOpeningAFile */);
577 }
558 578
559 this.summarizeSelection_(); 579 this.summarizeSelection_();
560 580
561 var sortField = 581 var sortField =
562 window.localStorage['sort-field-' + this.dialogType_] || 'cachedMtime_'; 582 window.localStorage['sort-field-' + this.dialogType_] || 'cachedMtime_';
563 var sortDirection = 583 var sortDirection =
564 window.localStorage['sort-direction-' + this.dialogType_] || 'desc'; 584 window.localStorage['sort-direction-' + this.dialogType_] || 'desc';
565 this.directoryModel_.fileList.sort(sortField, sortDirection); 585 this.directoryModel_.fileList.sort(sortField, sortDirection);
566 586
567 this.refocus(); 587 this.refocus();
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
630 this.filenameInput_ = this.dialogDom_.querySelector('.filename-input'); 650 this.filenameInput_ = this.dialogDom_.querySelector('.filename-input');
631 this.taskItems_ = this.dialogDom_.querySelector('.tasks'); 651 this.taskItems_ = this.dialogDom_.querySelector('.tasks');
632 this.okButton_ = this.dialogDom_.querySelector('.ok'); 652 this.okButton_ = this.dialogDom_.querySelector('.ok');
633 this.cancelButton_ = this.dialogDom_.querySelector('.cancel'); 653 this.cancelButton_ = this.dialogDom_.querySelector('.cancel');
634 this.deleteButton_ = this.dialogDom_.querySelector('.delete-button'); 654 this.deleteButton_ = this.dialogDom_.querySelector('.delete-button');
635 this.table_ = this.dialogDom_.querySelector('.detail-table'); 655 this.table_ = this.dialogDom_.querySelector('.detail-table');
636 this.grid_ = this.dialogDom_.querySelector('.thumbnail-grid'); 656 this.grid_ = this.dialogDom_.querySelector('.thumbnail-grid');
637 this.spinner_ = this.dialogDom_.querySelector('.spinner'); 657 this.spinner_ = this.dialogDom_.querySelector('.spinner');
638 this.showSpinner_(false); 658 this.showSpinner_(false);
639 this.butter_ = this.dialogDom_.querySelector('.butter-bar'); 659 this.butter_ = this.dialogDom_.querySelector('.butter-bar');
660 this.unmountedPanel_ = this.dialogDom_.querySelector('.unmounted-panel');
640 661
641 cr.ui.Table.decorate(this.table_); 662 cr.ui.Table.decorate(this.table_);
642 cr.ui.Grid.decorate(this.grid_); 663 cr.ui.Grid.decorate(this.grid_);
643 664
644 this.downloadsWarning_ = 665 this.downloadsWarning_ =
645 this.dialogDom_.querySelector('.downloads-warning'); 666 this.dialogDom_.querySelector('.downloads-warning');
646 var html = util.htmlUnescape(str('DOWNLOADS_DIRECTORY_WARNING')); 667 var html = util.htmlUnescape(str('DOWNLOADS_DIRECTORY_WARNING'));
647 this.downloadsWarning_.lastElementChild.innerHTML = html; 668 this.downloadsWarning_.lastElementChild.innerHTML = html;
648 var link = this.downloadsWarning_.querySelector('a'); 669 var link = this.downloadsWarning_.querySelector('a');
649 link.addEventListener('click', this.onDownloadsWarningClick_.bind(this)); 670 link.addEventListener('click', this.onDownloadsWarningClick_.bind(this));
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after
795 this.rootsList_.itemConstructor = function(entry) { 816 this.rootsList_.itemConstructor = function(entry) {
796 return self.renderRoot_(entry); 817 return self.renderRoot_(entry);
797 }; 818 };
798 819
799 this.rootsList_.selectionModel = this.directoryModel_.rootsListSelection; 820 this.rootsList_.selectionModel = this.directoryModel_.rootsListSelection;
800 821
801 // TODO(dgozman): add "Add a drive" item. 822 // TODO(dgozman): add "Add a drive" item.
802 this.rootsList_.dataModel = this.directoryModel_.rootsList; 823 this.rootsList_.dataModel = this.directoryModel_.rootsList;
803 this.directoryModel_.updateRoots(function() { 824 this.directoryModel_.updateRoots(function() {
804 self.rootsList_.endBatchUpdates(); 825 self.rootsList_.endBatchUpdates();
805 }); 826 }, false);
806 };
807
808 FileManager.prototype.initGData_ = function() {
809 metrics.startInterval('Load.GData');
810 chrome.fileBrowserPrivate.addMount('', 'gdata', {});
811 if (this.gdataMountTimer_) {
812 clearTimeout(this.gdataMountTimer_);
813 }
814 this.gdataMountTimer_ = setTimeout(function() {
815 this.gdataMountTimer_ = null;
816 if (this.isOnGData()) {
817 // TODO(kaznacheev): show the message in the file list space.
818 this.alert.show('Could not connect to GData');
819 }
820 }.bind(this), 10 * 1000);
821 }; 827 };
822 828
823 /** 829 /**
830 * @param {boolean} dirChanged True if we just changed to GData directory,
831 * False if "Retry" button clicked.
832 */
833 FileManager.prototype.initGData_ = function(dirChanged) {
834 this.initGDataUnmountedPanel_();
835
836 this.unmountedPanel_.removeAttribute('error');
837 if (dirChanged) {
838 // When changing to GData directory we want to see a clear panel.
839 this.unmountedPanel_.removeAttribute('retry');
840 if (this.gdataLoadingTimer_ ) { // Show immediately if already loading.
841 this.unmountedPanel_.setAttribute('loading', true);
842 } else {
843 this.unmountedPanel_.removeAttribute('loading');
844 setTimeout(function() {
845 if (this.gdataLoadingTimer_) { // Still loading.
846 this.unmountedPanel_.setAttribute('loading', true);
847 }
848 }.bind(this), 500);
849 }
850 } else {
851 // When retrying we do not hide "Retry" and "Learn more".
852 this.unmountedPanel_.setAttribute('loading', true);
853 }
854
855 // If the user changed to another directory and then back to GData we
856 // re-enter this method while the timer is still active. In this case
857 // we only update the UI but do not request the mount again.
858 if (this.gdataLoadingTimer_)
859 return;
860
861 metrics.startInterval('Load.GData');
862 chrome.fileBrowserPrivate.addMount('', 'gdata', {});
863
864 // This timer could fire before the mount succeeds. We will silently
865 // replace the error message with the correct directory contents.
866 this.gdataLoadingTimer_ = setTimeout(function() {
867 this.gdataLoadingTimer_ = null;
868 this.onGDataUnreachable_('GData load timeout');
869 }.bind(this),
870 10 * 1000) ;
871 };
872
873 FileManager.prototype.clearGDataLoadingTimer_ = function(message) {
874 if (this.gdataLoadingTimer_) {
875 clearTimeout(this.gdataLoadingTimer_);
876 this.gdataLoadingTimer_ = null;
877 }
878 };
879
880 FileManager.prototype.onGDataUnreachable_ = function(message) {
881 console.warn(message);
882 if (this.isOnGData()) {
883 this.unmountedPanel_.removeAttribute('loading');
884 this.unmountedPanel_.setAttribute('error', true);
885 this.unmountedPanel_.setAttribute('retry', true);
886 }
887 };
888
889 FileManager.prototype.initGDataUnmountedPanel_ = function() {
890 if (this.unmountedPanel_.firstElementChild)
891 return;
892
893 var loading = this.document_.createElement('div');
894 loading.className = 'gdata loading';
895 loading.textContent = strf('GDATA_LOADING', str('GDATA_PRODUCT_NAME'));
896 this.unmountedPanel_.appendChild(loading);
897
898 var error = this.document_.createElement('div');
899 error.className = 'gdata error';
900 error.textContent = strf('GDATA_CANNOT_REACH', str('GDATA_PRODUCT_NAME'));
901 this.unmountedPanel_.appendChild(error);
902
903 var retry = this.document_.createElement('button');
904 retry.className = 'gdata retry';
905 retry.textContent = str('GDATA_RETRY');
906 retry.onclick = this.initGData_.bind(this, false /* retry */);
907 this.unmountedPanel_.appendChild(retry);
908
909 var learnMore = this.document_.createElement('div');
910 learnMore.className = 'gdata learn-more';
911 this.unmountedPanel_.appendChild(learnMore);
912
913 var learnMoreLink = this.document_.createElement('a');
914 learnMoreLink.textContent = str('GDATA_LEARN_MORE');
915 learnMoreLink.href = 'javascript://'; // TODO: Set a proper link URL.
916 learnMoreLink.className = 'gdata learn-more';
917 learnMore.appendChild(learnMoreLink);
918 };
919
920 /**
824 * Get the icon type for a given Entry. 921 * Get the icon type for a given Entry.
825 * 922 *
826 * @param {Entry} entry An Entry subclass (FileEntry or DirectoryEntry). 923 * @param {Entry} entry An Entry subclass (FileEntry or DirectoryEntry).
827 * @return {string} 924 * @return {string}
828 */ 925 */
829 FileManager.prototype.getIconType = function(entry) { 926 FileManager.prototype.getIconType = function(entry) {
830 if (!('cachedIconType_' in entry)) 927 if (!('cachedIconType_' in entry))
831 entry.cachedIconType_ = this.computeIconType_(entry); 928 entry.cachedIconType_ = this.computeIconType_(entry);
832 return entry.cachedIconType_; 929 return entry.cachedIconType_;
833 }; 930 };
(...skipping 677 matching lines...) Expand 10 before | Expand all | Expand 10 after
1511 this.rootsList_.redraw(); 1608 this.rootsList_.redraw();
1512 this.truncateBreadcrumbs_(); 1609 this.truncateBreadcrumbs_();
1513 }; 1610 };
1514 1611
1515 FileManager.prototype.resolvePath = function( 1612 FileManager.prototype.resolvePath = function(
1516 path, resultCallback, errorCallback) { 1613 path, resultCallback, errorCallback) {
1517 return util.resolvePath(this.filesystem_.root, path, resultCallback, 1614 return util.resolvePath(this.filesystem_.root, path, resultCallback,
1518 errorCallback); 1615 errorCallback);
1519 }; 1616 };
1520 1617
1618 FileManager.prototype.getPathFromUrlOrParams_ = function() {
1619 return location.hash ? // Location hash has the highest priority.
1620 decodeURI(location.hash.substr(1)) :
1621 this.params_.defaultPath;
1622 };
1623
1521 /** 1624 /**
1522 * Restores current directory and may be a selected item after page load (or 1625 * Restores current directory and may be a selected item after page load (or
1523 * reload) or popping a state (after click on back/forward). If location.hash 1626 * reload) or popping a state (after click on back/forward). If location.hash
1524 * is present it means that the user has navigated somewhere and that place 1627 * is present it means that the user has navigated somewhere and that place
1525 * will be restored. defaultPath primarily is used with save/open dialogs. 1628 * will be restored. defaultPath primarily is used with save/open dialogs.
1526 * Default path may also contain a file name. Freshly opened file manager 1629 * Default path may also contain a file name. Freshly opened file manager
1527 * window has neither. 1630 * window has neither.
1631 *
1632 * @param {boolean} blankWhileOpeningAFile
1528 */ 1633 */
1529 FileManager.prototype.setupCurrentDirectory_ = function() { 1634 FileManager.prototype.setupCurrentDirectory_ =
1635 function(blankWhileOpeningAFile) {
1636 var path = this.getPathFromUrlOrParams_();
1530 1637
1531 if (location.hash) { 1638 if (!path) {
1532 // Location hash has the highest priority. 1639 this.directoryModel_.setupDefaultPath();
1533 var path = decodeURI(location.hash.substr(1)); 1640 return;
1641 }
1534 1642
1535 // In the FULL_PAGE mode if the path points to a file we might have 1643 // In the FULL_PAGE mode if the hash path points to a file we might have
1536 // to invoke a task after selecting it. 1644 // to invoke a task after selecting it.
1537 if (this.dialogType_ == FileManager.DialogType.FULL_PAGE) { 1645 // If the file path is in params_ we only want to select the file.
1538 // To prevent the file list flickering for a moment before the action 1646 if (location.hash &&
1539 // is executed we hide it under a white div. 1647 this.dialogType_ == FileManager.DialogType.FULL_PAGE) {
1540 var shade = this.document_.createElement('div'); 1648 // To prevent the file list flickering for a moment before the action
1649 // is executed we hide it under a white div.
1650 var shade;
1651 if (blankWhileOpeningAFile) {
1652 shade = this.document_.createElement('div');
1541 shade.className = 'overlay-pane'; 1653 shade.className = 'overlay-pane';
1542 shade.style.backgroundColor = 'white'; 1654 shade.style.backgroundColor = 'white';
1543 this.document_.body.appendChild(shade); 1655 this.document_.body.appendChild(shade);
1544 function removeShade() { shade.parentNode.removeChild(shade) } 1656 }
1545 1657 function removeShade() {
1546 // Keep track of whether the path is identified as an existing leaf 1658 if (shade)
1547 // node. Note that onResolve is guaranteed to be called (exactly once) 1659 shade.parentNode.removeChild(shade);
1548 // before onLoadedActivateLeaf.
1549 var foundLeaf = true;
1550 function onResolve(baseName, leafName, exists) {
1551 if (!exists || leafName == '') {
1552 // Non-existent file or a directory. Remove the shade immediately.
1553 removeShade();
1554 foundLeaf = false;
1555 }
1556 }
1557
1558 // TODO(kaznacheev): refactor dispatchDefaultTask to accept an array
1559 // of urls instead of a selection. This will remove the need to wait
1560 // until the selection is done.
1561 var self = this;
1562 function onLoadedActivateLeaf() {
1563 if (foundLeaf) {
1564 // There are 3 ways we can get here:
1565 // 1. Invoked from file_manager_util::ViewFile. This can only
1566 // happen for 'gallery' and 'mount-archive' actions.
1567 // 2. Reloading a Gallery page. Must be an image or a video file.
1568 // 3. A user manually entered a URL pointing to a file.
1569 if (FileType.isImageOrVideo(path)) {
1570 self.dispatchInternalTask_('gallery', self.selection.urls);
1571 } else if (FileType.getMediaType(path) == 'archive') {
1572 self.dispatchInternalTask_('mount-archive', self.selection.urls);
1573 } else {
1574 // Manually entered path, do nothing, remove the shade ASAP.
1575 removeShade();
1576 return;
1577 }
1578 setTimeout(removeShade, 1000);
1579 }
1580 }
1581 this.directoryModel_.setupPath(path, onLoadedActivateLeaf, onResolve);
1582
1583 return;
1584 } 1660 }
1585 1661
1586 this.directoryModel_.setupPath(path); 1662 // Keep track of whether the path is identified as an existing leaf
1663 // node. Note that onResolve is guaranteed to be called (exactly once)
1664 // before onLoadedActivateLeaf.
1665 var foundLeaf = true;
1666 function onResolve(baseName, leafName, exists) {
1667 if (!exists || leafName == '') {
1668 // Non-existent file or a directory. Remove the shade immediately.
1669 removeShade();
1670 foundLeaf = false;
1671 }
1672 }
1673
1674 // TODO(kaznacheev): refactor dispatchDefaultTask to accept an array
1675 // of urls instead of a selection. This will remove the need to wait
1676 // until the selection is done.
1677 var self = this;
1678 function onLoadedActivateLeaf() {
1679 if (foundLeaf) {
1680 // There are 3 ways we can get here:
1681 // 1. Invoked from file_manager_util::ViewFile. This can only
1682 // happen for 'gallery' and 'mount-archive' actions.
1683 // 2. Reloading a Gallery page. Must be an image or a video file.
1684 // 3. A user manually entered a URL pointing to a file.
1685 if (FileType.isImageOrVideo(path)) {
1686 self.dispatchInternalTask_('gallery', self.selection.urls);
1687 } else if (FileType.getMediaType(path) == 'archive') {
1688 self.dispatchInternalTask_('mount-archive', self.selection.urls);
1689 } else {
1690 // Manually entered path, do nothing, remove the shade ASAP.
1691 removeShade();
1692 return;
1693 }
1694 setTimeout(removeShade, 1000);
1695 }
1696 }
1697 this.directoryModel_.setupPath(path, onLoadedActivateLeaf, onResolve);
1587 return; 1698 return;
1588 } 1699 }
1589 1700
1590 if (this.params_.defaultPath) { 1701 if (this.dialogType_ == FileManager.DialogType.SELECT_SAVEAS_FILE) {
1591 var path = this.params_.defaultPath; 1702 this.directoryModel_.setupPath(path, undefined,
1592 if (this.dialogType_ == FileManager.DialogType.SELECT_SAVEAS_FILE) { 1703 function(basePath, leafName) {
1593 this.directoryModel_.setupPath(path, undefined, 1704 this.filenameInput_.value = leafName;
1594 function(basePath, leafName) { 1705 this.selectDefaultPathInFilenameInput_();
1595 this.filenameInput_.value = leafName; 1706 }.bind(this));
1596 this.selectDefaultPathInFilenameInput_();
1597 }.bind(this));
1598 return;
1599 }
1600
1601 this.directoryModel_.setupPath(path);
1602 return; 1707 return;
1603 } 1708 }
1604 1709
1605 this.directoryModel_.setupDefaultPath(); 1710 this.directoryModel_.setupPath(path);
1606 }; 1711 };
1607 1712
1608 /** 1713 /**
1609 * Tweak the UI to become a particular kind of dialog, as determined by the 1714 * Tweak the UI to become a particular kind of dialog, as determined by the
1610 * dialog type parameter passed to the constructor. 1715 * dialog type parameter passed to the constructor.
1611 */ 1716 */
1612 FileManager.prototype.initDialogType_ = function() { 1717 FileManager.prototype.initDialogType_ = function() {
1613 var defaultTitle; 1718 var defaultTitle;
1614 var okLabel = str('OPEN_LABEL'); 1719 var okLabel = str('OPEN_LABEL');
1615 1720
(...skipping 888 matching lines...) Expand 10 before | Expand all | Expand 10 after
2504 2609
2505 if (selection.tasksList.length > 0) { 2610 if (selection.tasksList.length > 0) {
2506 this.dispatchFileTask_(selection.tasksList[0].taskId, selection.urls); 2611 this.dispatchFileTask_(selection.tasksList[0].taskId, selection.urls);
2507 return; 2612 return;
2508 } 2613 }
2509 2614
2510 if (selection.urls.length == 1) { 2615 if (selection.urls.length == 1) {
2511 // We don't have tasks, so try the default browser action. 2616 // We don't have tasks, so try the default browser action.
2512 // We only do that for single selection to avoid confusion. 2617 // We only do that for single selection to avoid confusion.
2513 2618
2514 function callback(success) { 2619 var callback = function(success) {
2515 if (!success && selection.entries.length == 1) 2620 if (!success && selection.entries.length == 1)
2516 this.alert.showHtml( 2621 this.alert.showHtml(
2517 unescape(selection.entries[0].name), 2622 unescape(selection.entries[0].name),
2518 strf('NO_ACTION_FOR_FILE', NO_ACTION_FOR_FILE_URL), 2623 strf('NO_ACTION_FOR_FILE', NO_ACTION_FOR_FILE_URL),
2519 function() {}); 2624 function() {});
2520 } 2625 }.bind(this);
2521 2626
2522 this.executeIfAvailable_(selection.urls, function(urls) { 2627 this.executeIfAvailable_(selection.urls, function(urls) {
2523 chrome.fileBrowserPrivate.viewFiles(urls, 'default', 2628 chrome.fileBrowserPrivate.viewFiles(urls, 'default', callback);
2524 callback.bind(this));
2525 }); 2629 });
2526 } 2630 }
2527 }; 2631 };
2528 2632
2529 FileManager.prototype.dispatchInternalTask_ = function(task, urls) { 2633 FileManager.prototype.dispatchInternalTask_ = function(task, urls) {
2530 this.dispatchFileTask_(this.getExtensionId_() + '|' + task, urls); 2634 this.dispatchFileTask_(this.getExtensionId_() + '|' + task, urls);
2531 }; 2635 };
2532 2636
2533 FileManager.prototype.dispatchFileTask_ = function(taskId, urls) { 2637 FileManager.prototype.dispatchFileTask_ = function(taskId, urls) {
2534 this.executeIfAvailable_(urls, function(urls) { 2638 this.executeIfAvailable_(urls, function(urls) {
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
2586 /** 2690 /**
2587 * Event handler called when some volume was mounted or unmouted. 2691 * Event handler called when some volume was mounted or unmouted.
2588 */ 2692 */
2589 FileManager.prototype.onMountCompleted_ = function(event) { 2693 FileManager.prototype.onMountCompleted_ = function(event) {
2590 var self = this; 2694 var self = this;
2591 2695
2592 var changeDirectoryTo = null; 2696 var changeDirectoryTo = null;
2593 2697
2594 if (event && event.mountType == 'gdata') { 2698 if (event && event.mountType == 'gdata') {
2595 metrics.recordInterval('Load.GData'); 2699 metrics.recordInterval('Load.GData');
2596 if (this.gdataMountTimer_) { 2700 console.log("GData mounted");
2597 clearTimeout(this.gdataMountTimer_);
2598 this.gdataMountTimer_ = null;
2599 }
2600 if (event.status == 'success') { 2701 if (event.status == 'success') {
2601 this.gdataMounted_ = true; 2702 this.gdataMounted_ = true;
2602 this.gdataMountInfo_ = { 2703 this.gdataMountInfo_ = {
2603 "mountPath": event.mountPath, 2704 "mountPath": event.mountPath,
2604 "sourceUrl": event.sourceUrl, 2705 "sourceUrl": event.sourceUrl,
2605 "mountType": event.mountType, 2706 "mountType": event.mountType,
2606 "mountCondition": event.status 2707 "mountCondition": event.status
2607 }; 2708 };
2608 if (this.isOnGData()) { 2709 // Not calling clearGDataLoadingTimer_ here because we want to keep
2710 // "Loading Google Docs" message until the directory loads. It is OK if
2711 // the timer fires after the mount because onDirectoryChanged_ will hide
2712 // the unmounted panel.
2713 if (this.setupCurrentDirectoryPostponed_) {
2714 this.setupCurrentDirectoryPostponed_(false);
dgozman 2012/03/28 14:18:36 Comment about meaning of this |false|.
2715 } else if (this.isOnGData() &&
2716 this.directoryModel_.currentEntry.unmounted) {
2609 // We are currently on an unmounted GData directory, force a rescan. 2717 // We are currently on an unmounted GData directory, force a rescan.
2610 changeDirectoryTo = this.directoryModel_.rootPath; 2718 changeDirectoryTo = this.directoryModel_.rootPath;
2611 } 2719 }
2612 } else { 2720 } else {
2613 this.gdataMounted_ = false; 2721 this.gdataMounted_ = false;
2614 this.gdataMountInfo_ = null; 2722 this.gdataMountInfo_ = null;
2723 this.clearGDataLoadingTimer_();
2724 this.onGDataUnreachable_('GData mount failed: ' + event.status);
2725 if (this.setupCurrentDirectoryPostponed_) {
2726 this.setupCurrentDirectoryPostponed_(true); // Cancel.
2727 // Change to unmounted GData root.
2728 changeDirectoryTo = '/' + DirectoryModel.GDATA_DIRECTORY;
2729 }
2615 } 2730 }
2616 } 2731 }
2617 2732
2618 chrome.fileBrowserPrivate.getMountPoints(function(mountPoints) { 2733 chrome.fileBrowserPrivate.getMountPoints(function(mountPoints) {
2619 self.setMountPoints_(mountPoints); 2734 self.setMountPoints_(mountPoints);
2620 if (event.eventType == 'mount') { 2735 if (event.eventType == 'mount') {
2621 // Mount request finished - remove it. 2736 // Mount request finished - remove it.
2622 var index = self.mountRequests_.indexOf(event.sourceUrl); 2737 var index = self.mountRequests_.indexOf(event.sourceUrl);
2623 if (index != -1) { 2738 if (index != -1) {
2624 self.mountRequests_.splice(index, 1); 2739 self.mountRequests_.splice(index, 1);
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
2660 changeDirectoryTo = '/' + DirectoryModel.DOWNLOADS_DIRECTORY; 2775 changeDirectoryTo = '/' + DirectoryModel.DOWNLOADS_DIRECTORY;
2661 } 2776 }
2662 2777
2663 // Even if something failed root list should be rescanned. 2778 // Even if something failed root list should be rescanned.
2664 // Failed mounts can "give" us new devices which might be formatted, 2779 // Failed mounts can "give" us new devices which might be formatted,
2665 // so we have to refresh root list then. 2780 // so we have to refresh root list then.
2666 self.directoryModel_.updateRoots(function() { 2781 self.directoryModel_.updateRoots(function() {
2667 if (changeDirectoryTo) { 2782 if (changeDirectoryTo) {
2668 self.directoryModel_.changeDirectory(changeDirectoryTo); 2783 self.directoryModel_.changeDirectory(changeDirectoryTo);
2669 } 2784 }
2670 }); 2785 }, self.gdataMounted_);
2671 }); 2786 });
2672 }; 2787 };
2673 2788
2674 /** 2789 /**
2675 * Event handler called when some internal task should be executed. 2790 * Event handler called when some internal task should be executed.
2676 */ 2791 */
2677 FileManager.prototype.onFileTaskExecute_ = function(id, urls) { 2792 FileManager.prototype.onFileTaskExecute_ = function(id, urls) {
2678 if (id == 'play') { 2793 if (id == 'play') {
2679 var position = 0; 2794 var position = 0;
2680 if (urls.length == 1) { 2795 if (urls.length == 1) {
(...skipping 869 matching lines...) Expand 10 before | Expand all | Expand 10 after
3550 } 3665 }
3551 chrome.fileBrowserPrivate.removeFileWatch(this.watchedDirectoryUrl_, 3666 chrome.fileBrowserPrivate.removeFileWatch(this.watchedDirectoryUrl_,
3552 function(result) { 3667 function(result) {
3553 if (!result) { 3668 if (!result) {
3554 console.log('Failed to remove file watch'); 3669 console.log('Failed to remove file watch');
3555 } 3670 }
3556 }); 3671 });
3557 this.watchedDirectoryUrl_ = null; 3672 this.watchedDirectoryUrl_ = null;
3558 } 3673 }
3559 3674
3560 if (event.newDirEntry.fullPath != '/') { 3675 if (event.newDirEntry.fullPath != '/' && !event.newDirEntry.unmounted) {
3561 this.watchedDirectoryUrl_ = event.newDirEntry.toURL(); 3676 this.watchedDirectoryUrl_ = event.newDirEntry.toURL();
3562 chrome.fileBrowserPrivate.addFileWatch(this.watchedDirectoryUrl_, 3677 chrome.fileBrowserPrivate.addFileWatch(this.watchedDirectoryUrl_,
3563 function(result) { 3678 function(result) {
3564 if (!result) { 3679 if (!result) {
3565 console.log('Failed to add file watch'); 3680 console.log('Failed to add file watch');
3566 this.watchedDirectoryUrl_ = null; 3681 this.watchedDirectoryUrl_ = null;
3567 } 3682 }
3568 }.bind(this)); 3683 }.bind(this));
3569 } 3684 }
3570 3685
3571 this.updateVolumeMetadata_(); 3686 this.updateVolumeMetadata_();
3572 3687
3688 if (event.newDirEntry.unmounted)
3689 this.dialogContainer_.setAttribute('unmounted', true);
3690 else
3691 this.dialogContainer_.removeAttribute('unmounted');
3692
3573 if (this.isOnGData()) { 3693 if (this.isOnGData()) {
3574 this.dialogContainer_.setAttribute('gdata', true); 3694 this.dialogContainer_.setAttribute('gdata', true);
3575 if (!this.requestedGDataMount_) { // Request GData mount only once. 3695 if (event.newDirEntry.unmounted) {
3576 this.requestedGDataMount_ = true; 3696 this.initGData_(true /* directory changed */);
3577 this.initGData_();
3578 } 3697 }
3579 } else { 3698 } else {
3580 this.dialogContainer_.removeAttribute('gdata'); 3699 this.dialogContainer_.removeAttribute('gdata');
3581 } 3700 }
3582 }; 3701 };
3583 3702
3584 FileManager.prototype.updateVolumeMetadata_ = function() { 3703 FileManager.prototype.updateVolumeMetadata_ = function() {
3585 var dm = this.directoryModel_; 3704 var dm = this.directoryModel_;
3586 if (!dm) return; 3705 if (!dm) return;
3587 3706
(...skipping 844 matching lines...) Expand 10 before | Expand all | Expand 10 after
4432 }); 4551 });
4433 }, onError); 4552 }, onError);
4434 4553
4435 function onError(err) { 4554 function onError(err) {
4436 console.log('Error while checking free space: ' + err); 4555 console.log('Error while checking free space: ' + err);
4437 setTimeout(doCheck, 1000 * 60); 4556 setTimeout(doCheck, 1000 * 60);
4438 } 4557 }
4439 } 4558 }
4440 } 4559 }
4441 })(); 4560 })();
OLDNEW
« no previous file with comments | « chrome/browser/resources/file_manager/js/directory_model.js ('k') | chrome/browser/resources/file_manager/main.html » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698