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

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: Rebase, 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 893 matching lines...) Expand 10 before | Expand all | Expand 10 after
2509 2614
2510 if (selection.tasksList.length > 0) { 2615 if (selection.tasksList.length > 0) {
2511 this.dispatchFileTask_(selection.tasksList[0].taskId, selection.urls); 2616 this.dispatchFileTask_(selection.tasksList[0].taskId, selection.urls);
2512 return; 2617 return;
2513 } 2618 }
2514 2619
2515 if (selection.urls.length == 1) { 2620 if (selection.urls.length == 1) {
2516 // We don't have tasks, so try the default browser action. 2621 // We don't have tasks, so try the default browser action.
2517 // We only do that for single selection to avoid confusion. 2622 // We only do that for single selection to avoid confusion.
2518 2623
2519 function callback(success) { 2624 var callback = function(success) {
2520 if (!success && selection.entries.length == 1) 2625 if (!success && selection.entries.length == 1)
2521 this.alert.showHtml( 2626 this.alert.showHtml(
2522 unescape(selection.entries[0].name), 2627 unescape(selection.entries[0].name),
2523 strf('NO_ACTION_FOR_FILE', NO_ACTION_FOR_FILE_URL), 2628 strf('NO_ACTION_FOR_FILE', NO_ACTION_FOR_FILE_URL),
2524 function() {}); 2629 function() {});
2525 } 2630 }.bind(this);
2526 2631
2527 this.executeIfAvailable_(selection.urls, function(urls) { 2632 this.executeIfAvailable_(selection.urls, function(urls) {
2528 chrome.fileBrowserPrivate.viewFiles(urls, 'default', 2633 chrome.fileBrowserPrivate.viewFiles(urls, 'default', callback);
2529 callback.bind(this));
2530 }); 2634 });
2531 } 2635 }
2532 }; 2636 };
2533 2637
2534 FileManager.prototype.dispatchInternalTask_ = function(task, urls) { 2638 FileManager.prototype.dispatchInternalTask_ = function(task, urls) {
2535 this.dispatchFileTask_(this.getExtensionId_() + '|' + task, urls); 2639 this.dispatchFileTask_(this.getExtensionId_() + '|' + task, urls);
2536 }; 2640 };
2537 2641
2538 FileManager.prototype.dispatchFileTask_ = function(taskId, urls) { 2642 FileManager.prototype.dispatchFileTask_ = function(taskId, urls) {
2539 this.executeIfAvailable_(urls, function(urls) { 2643 this.executeIfAvailable_(urls, function(urls) {
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
2591 /** 2695 /**
2592 * Event handler called when some volume was mounted or unmouted. 2696 * Event handler called when some volume was mounted or unmouted.
2593 */ 2697 */
2594 FileManager.prototype.onMountCompleted_ = function(event) { 2698 FileManager.prototype.onMountCompleted_ = function(event) {
2595 var self = this; 2699 var self = this;
2596 2700
2597 var changeDirectoryTo = null; 2701 var changeDirectoryTo = null;
2598 2702
2599 if (event && event.mountType == 'gdata') { 2703 if (event && event.mountType == 'gdata') {
2600 metrics.recordInterval('Load.GData'); 2704 metrics.recordInterval('Load.GData');
2601 if (this.gdataMountTimer_) { 2705 console.log("GData mounted");
2602 clearTimeout(this.gdataMountTimer_);
2603 this.gdataMountTimer_ = null;
2604 }
2605 if (event.status == 'success') { 2706 if (event.status == 'success') {
2606 this.gdataMounted_ = true; 2707 this.gdataMounted_ = true;
2607 this.gdataMountInfo_ = { 2708 this.gdataMountInfo_ = {
2608 "mountPath": event.mountPath, 2709 "mountPath": event.mountPath,
2609 "sourceUrl": event.sourceUrl, 2710 "sourceUrl": event.sourceUrl,
2610 "mountType": event.mountType, 2711 "mountType": event.mountType,
2611 "mountCondition": event.status 2712 "mountCondition": event.status
2612 }; 2713 };
2613 if (this.isOnGData()) { 2714 // Not calling clearGDataLoadingTimer_ here because we want to keep
2715 // "Loading Google Docs" message until the directory loads. It is OK if
2716 // the timer fires after the mount because onDirectoryChanged_ will hide
2717 // the unmounted panel.
2718 if (this.setupCurrentDirectoryPostponed_) {
2719 this.setupCurrentDirectoryPostponed_(false /* execute */);
2720 } else if (this.isOnGData() &&
2721 this.directoryModel_.currentEntry.unmounted) {
2614 // We are currently on an unmounted GData directory, force a rescan. 2722 // We are currently on an unmounted GData directory, force a rescan.
2615 changeDirectoryTo = this.directoryModel_.rootPath; 2723 changeDirectoryTo = this.directoryModel_.rootPath;
2616 } 2724 }
2617 } else { 2725 } else {
2618 this.gdataMounted_ = false; 2726 this.gdataMounted_ = false;
2619 this.gdataMountInfo_ = null; 2727 this.gdataMountInfo_ = null;
2728 this.clearGDataLoadingTimer_();
2729 this.onGDataUnreachable_('GData mount failed: ' + event.status);
2730 if (this.setupCurrentDirectoryPostponed_) {
2731 this.setupCurrentDirectoryPostponed_(true /* cancel */);
2732 // Change to unmounted GData root.
2733 changeDirectoryTo = '/' + DirectoryModel.GDATA_DIRECTORY;
2734 }
2620 } 2735 }
2621 } 2736 }
2622 2737
2623 chrome.fileBrowserPrivate.getMountPoints(function(mountPoints) { 2738 chrome.fileBrowserPrivate.getMountPoints(function(mountPoints) {
2624 self.setMountPoints_(mountPoints); 2739 self.setMountPoints_(mountPoints);
2625 if (event.eventType == 'mount') { 2740 if (event.eventType == 'mount') {
2626 // Mount request finished - remove it. 2741 // Mount request finished - remove it.
2627 var index = self.mountRequests_.indexOf(event.sourceUrl); 2742 var index = self.mountRequests_.indexOf(event.sourceUrl);
2628 if (index != -1) { 2743 if (index != -1) {
2629 self.mountRequests_.splice(index, 1); 2744 self.mountRequests_.splice(index, 1);
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
2665 changeDirectoryTo = '/' + DirectoryModel.DOWNLOADS_DIRECTORY; 2780 changeDirectoryTo = '/' + DirectoryModel.DOWNLOADS_DIRECTORY;
2666 } 2781 }
2667 2782
2668 // Even if something failed root list should be rescanned. 2783 // Even if something failed root list should be rescanned.
2669 // Failed mounts can "give" us new devices which might be formatted, 2784 // Failed mounts can "give" us new devices which might be formatted,
2670 // so we have to refresh root list then. 2785 // so we have to refresh root list then.
2671 self.directoryModel_.updateRoots(function() { 2786 self.directoryModel_.updateRoots(function() {
2672 if (changeDirectoryTo) { 2787 if (changeDirectoryTo) {
2673 self.directoryModel_.changeDirectory(changeDirectoryTo); 2788 self.directoryModel_.changeDirectory(changeDirectoryTo);
2674 } 2789 }
2675 }); 2790 }, self.gdataMounted_);
2676 }); 2791 });
2677 }; 2792 };
2678 2793
2679 /** 2794 /**
2680 * Event handler called when some internal task should be executed. 2795 * Event handler called when some internal task should be executed.
2681 */ 2796 */
2682 FileManager.prototype.onFileTaskExecute_ = function(id, urls) { 2797 FileManager.prototype.onFileTaskExecute_ = function(id, urls) {
2683 if (id == 'play') { 2798 if (id == 'play') {
2684 var position = 0; 2799 var position = 0;
2685 if (urls.length == 1) { 2800 if (urls.length == 1) {
(...skipping 869 matching lines...) Expand 10 before | Expand all | Expand 10 after
3555 } 3670 }
3556 chrome.fileBrowserPrivate.removeFileWatch(this.watchedDirectoryUrl_, 3671 chrome.fileBrowserPrivate.removeFileWatch(this.watchedDirectoryUrl_,
3557 function(result) { 3672 function(result) {
3558 if (!result) { 3673 if (!result) {
3559 console.log('Failed to remove file watch'); 3674 console.log('Failed to remove file watch');
3560 } 3675 }
3561 }); 3676 });
3562 this.watchedDirectoryUrl_ = null; 3677 this.watchedDirectoryUrl_ = null;
3563 } 3678 }
3564 3679
3565 if (event.newDirEntry.fullPath != '/') { 3680 if (event.newDirEntry.fullPath != '/' && !event.newDirEntry.unmounted) {
3566 this.watchedDirectoryUrl_ = event.newDirEntry.toURL(); 3681 this.watchedDirectoryUrl_ = event.newDirEntry.toURL();
3567 chrome.fileBrowserPrivate.addFileWatch(this.watchedDirectoryUrl_, 3682 chrome.fileBrowserPrivate.addFileWatch(this.watchedDirectoryUrl_,
3568 function(result) { 3683 function(result) {
3569 if (!result) { 3684 if (!result) {
3570 console.log('Failed to add file watch'); 3685 console.log('Failed to add file watch');
3571 this.watchedDirectoryUrl_ = null; 3686 this.watchedDirectoryUrl_ = null;
3572 } 3687 }
3573 }.bind(this)); 3688 }.bind(this));
3574 } 3689 }
3575 3690
3576 this.updateVolumeMetadata_(); 3691 this.updateVolumeMetadata_();
3577 3692
3693 if (event.newDirEntry.unmounted)
3694 this.dialogContainer_.setAttribute('unmounted', true);
3695 else
3696 this.dialogContainer_.removeAttribute('unmounted');
3697
3578 if (this.isOnGData()) { 3698 if (this.isOnGData()) {
3579 this.dialogContainer_.setAttribute('gdata', true); 3699 this.dialogContainer_.setAttribute('gdata', true);
3580 if (!this.requestedGDataMount_) { // Request GData mount only once. 3700 if (event.newDirEntry.unmounted) {
3581 this.requestedGDataMount_ = true; 3701 this.initGData_(true /* directory changed */);
3582 this.initGData_();
3583 } 3702 }
3584 } else { 3703 } else {
3585 this.dialogContainer_.removeAttribute('gdata'); 3704 this.dialogContainer_.removeAttribute('gdata');
3586 } 3705 }
3587 }; 3706 };
3588 3707
3589 FileManager.prototype.updateVolumeMetadata_ = function() { 3708 FileManager.prototype.updateVolumeMetadata_ = function() {
3590 var dm = this.directoryModel_; 3709 var dm = this.directoryModel_;
3591 if (!dm) return; 3710 if (!dm) return;
3592 3711
(...skipping 844 matching lines...) Expand 10 before | Expand all | Expand 10 after
4437 }); 4556 });
4438 }, onError); 4557 }, onError);
4439 4558
4440 function onError(err) { 4559 function onError(err) {
4441 console.log('Error while checking free space: ' + err); 4560 console.log('Error while checking free space: ' + err);
4442 setTimeout(doCheck, 1000 * 60); 4561 setTimeout(doCheck, 1000 * 60);
4443 } 4562 }
4444 } 4563 }
4445 } 4564 }
4446 })(); 4565 })();
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